The current anatomy of a good movie: Can we do better?

Ever since the “Golden Age” of cinema in the 1930s that marked silent film a thing of the past, the film industry has witnessed unparalleled success and growth. From the first technicolor movies like The Wizard of Oz and Gone With The Wind to the computationally animated The Matrix, Jurassic Park, and the first fully computer-animated film, Toy Story, the industry of motion pictures has contributed greatly not only to technology but also the global economy. Especially in the current challenging economy and there has been a sharp decline in theater audience—[shrinking by half in the last 4 years]https://en.wikipedia.org/wiki/IMDb), film distributors are hesitant to take on a movie unless they can see its success first hand. Therefore, box-office, or the entire earnings generated through movie ticket sales, has been recognized as one of the primary indicators to compare film success. Many rely on it to decide whether to both produce and watch a film. However, are high grossing movies actually… good? If so, what else can we use to measure them?

One of the popular other indicators used worldwide to assess a movie is IMDb rating (or International Movie Database). IMDb rating allows 83 million of its registered users to cast a vote (from 1 to 10) on every released title in the database. These votes are then aggregated and summarized as a single IMDb rating visible on IMDb.com. Accessible to anyone, anywhere, these ratings are a simplified way to see what people all over the world think about movies and have been an often-used indicator for a film’s popularity/quality. This led us to wonder: How do the most profitable movies rank on the IMDb website?

From our visualization above, the top 20 grossing films have a range of scores from 6.2 to 8.4 stars. Conversely, the top 20 scored movies on IMDb globally grossed between 28,419,159 and 1,120,210,896 U.S. Dollars. When comparing the IMDbscore and amount of money grossed, we can observe that there isn’t much of a relationship between the rating of a film (or how “objectively good” a movie is) and the amount of money it makes.

On the other hand, to investigate opinions of films from professionals and trusted members of the film industry, we can turn to the Academy Awards.

This scatter plot displays the top 20 highest grossing movies of all time by their profit and the main character's race. It shows that out of 20 movies, 2 has a non-white main character.

It seems like a movie’s revenue is not a strong indicator for its accolades. Among the top 20 movies with the highest worldwide box office and their Oscars awards, only 11 movies had any nominations at all. Furthermore, this list gets even more narrowed down as we look into wins/loses. Titanic, Avatar, Black Panther, and Frozen are the only movies in the top 20 highest worldwide grossing movies to have had at least one nomination and won, with Titanic as the most prolific with 11 out of 14 categories (after grouping some of them together).

The Oscars, however, are not an objective means of awardship. In 2015, the academy “awarded all 20 acting nominations to white actors for the first of two consecutive years, inspiring April Reign to create the hashtag #OscarsSoWhite” (Ugwu, 2020). Leaving the determination of film success to the Academy seems to yield a celebration of white creators and artists, excluding a whole world of diverse cinema.

This scatter plot displays the top 20 highest grossing movies of all time by their profit and the main character's race. It shows that out of 20 movies, 2 has a non-white main character.

As of 2020, almost half of the U.S. population (42.2%) are people of color. Yet, Hollywood fails to consider them when making movies. In the top 20 highest grossing movies of all time, only 2 movies featured a non-white main character—both of which were Black males. None of these movies are in the top 5 of this list in terms of profit and grossing while other underrepresented demographics (Latines, East/South/Southeast Asians, Native Americans, Afro Latinos, etc.) are left completely off the screen.

Furthermore, in the history of the Oscars only three women have won the coveted best director title. This reflects a gendered measure of success within the film industry, where most of the praise goes to films about and created by cis men. To measure the representation of women in films, we can turn to the Bechdel test which was popularized by Alison Bechdel. The test names three simple criteria: (1) it has to have at least two women in it, who (2) who talk to each other, about (3) something besides a man. Although this test seems easy enough, only 25% of the top scored films and 50% of the top grossing films passed. Interestingly enough, when comparing the two datasets to an average Bechdel test score breakdown, we can see that the highest grossing films all have women and an above average score of “ok” and “dubious”. However, the highest scored films have less than average “ok” and dubious” scores.

The trend we have identified here is strong: movies that make the most money are most often than not white-, male-, and Euro-centric. Even looking beyond the dollar, we can see how scoring systems and awards are biased towards this demographic as well. Although the American movie industry continues achieved commercial success, it historically has, and continues to, lack sufficient representation. While Hollywood has undoubtedly created notable films like The Wizard of Oz, Gone With The Wind, The Matrix, and Jurassic Park, the industry’s focus on white males has resulted in a significant loss of diverse perspectives and cinematic experiences. It seems like when we are trying to judge a movie, we should have a broader repertoire of measurements for how good it is other than just money.

Data Description

All of our datasets was scraped from public domains such as kaggle.com and fivethirtyeight. In total, we used 4 datasets to support our research paper:

  1. The Oscar Award, 1927 - 2023:
  • 10,765 Oscar nominations
  • scraped from the Official Academy Awards
  • 7 variables: year, name, film, categories, win,…
  1. Movie Industry: Four decades of movies, 1986-2016:
  • 6820 movies in the dataset (around 220 movies per year)
  • 15 variables: budget, company, country, director, genre, name,….
  1. All Time Worldwide Box Office, 1939-2021
  • contains the top movies based on the cumulative worldwide box office
  • 7512 movies and 6 variables: rank, worldwide-international-domestic box office,…
  1. Bechdel Test, 1970-2013 (from library(fivethirtyeight))
  • tests whether movies meet the following criteria: There are ≥ 2 (named) female characters;these women talk to each othe; about something other than a man.
  • 1794 movies, 15 variables: movie, result, grossings, …

Limitations

Data

There are some limitations in the datasets. Firstmost, when comparing the worldwide grossing amount of movies, we were unable to account for inflation. The dataset “All Time Worldwide Box Office” scraped the the amounts of international grossing from 1939 to 2021, but IMDb states that “all figures are not adjusted for inflation”.
According to a Minnesotan inflation calculator 1 U.S. Dollar in 1939 is worth $19.48 today, which means that the amount of money occurring in different time periods is not scaled to size. Additionally, in the dataset used for the racial distribution of Oscars winners, the dataset only contained the racial identities of best directors, actors, and actresses. This excludes 21 other award categories, which could have given more accurate insight into the demographics of Oscars winners across the entire award ceremony.

Furthermore, we used IMDb ratings to investigate how movies of various grossing amounts are scored, but it is worth noting that the website calculates an overall score from registered users casting their votes. However, there has been a larger discussion around the methodology of this system of movie-rating, with some people deeming online movie voting systems to be ineffective. Additionally, it was found that “most IMDb voters are male, which seems to skew the ranking in favour of films that are aimed more towards men” (Reynolds, 2017). It is worth acknowledging that IMDb ratings are a biased system of ranking a film, however, this further aids our research question in illustrating the complications that come with determining whether a movie is “good”.
Another limitation of this project is using The Bechdel test as a measure of gender equality in film. The Bechdel test is an infamous measure of Hollywood’s gender imbalance, however it is an oversimplified means of analyzing the role of women in film. It asks three questions of a movie, and while astonishingly many films do not pass that bar, the simplicity of this test “doesn’t address the core inequalities in Hollywood films” (Hickey et al, 2017). In the dataset we used, there were many instances of “dubious” where the role of women in the film were debated, and therefore, the pass/fail score couldn’t be determined. To create a more holistic analysis of gender equality in Hollywood in the future, it is worth researching new tests that include non-binary people, and expand the requirements. For ideas, we can turn to “We pitted 50 movies against 12 new ways of measuring Hollywood’s gender imbalance” which suggests new tests that look beyond white women, and the cast and crew of the film.

Visualizations/ Overall Research

Our attempt throughout this research is to suggest different metrics to compare and conclude a movie quality and public performance other than its revenue and profit returns. Despite the various indicators we have included to offer other avenues in determining a good movie, our “tests” are simply not enough. With the limited scope of available and “perfect” data, our research face real world limitations that fail to ascertain the severity and array of Hollywood’s inequalities that are beyond the white male population. It also leaves out the population that stands behind the camera in movie production such as screenwriters, producers, set designers, etc. All of these are, hence, reflected in our visualizations. However, we hope that our research can serve as an incentive for the film industry as well as its audience to be more critical of movies and movie making.

Code Appendix

library(tidyverse)
library(splitstackshape)
library(dbplyr)
library(stringr)
library(readr)
library(ggplot2)
library(ggthemes)
library(fivethirtyeight)
library(highcharter)
library(scales)
library(rvest)
library(scales)
library(plotly)
library(gapminder)
library(forcats)
library(magrittr)


#Loading raw data
box_office <-read_csv("All Time Worldwide Box Office.csv")
movies_info <- read_csv("movies.csv")
oscars_award <- read_csv("the_oscar_award.csv")
bechdel <- data.frame(bechdel)
bechdelset <- read_csv("bechdelset.csv")
Bechdelmoney <- read_csv("Bechdelmoney.csv")
biopics <- data.frame(biopics)
RatingGross <- read_csv("RatingGross_edit2.csv")
#Data cleaning for figure 1
#average grossing for each top 20 scored

top_score <- movies_info %>% 
  select(name, score, year, gross) %>% 
  arrange(desc(score))

#average grossing for each top 20 scored

low_score <- movies_info %>% 
  select(name, score, year, gross) %>% 
  arrange(score)



oscarwins <-  movies_info %>% 
  filter(name %in% c("The Lord of the Rings: The Return of the King", "Titanic", "Ben-Hur", "West Side Story", "The English Patient", "The Last Emperor", "Gigi", "Slumdog Millionaire", "Amadeus", "Gandhi")) %>% 
 summarize(sum=sum(gross))

movies_info %>%
  group_by(year) %>%
  summarize(total_movies = n(),
            american_movies = sum(country == "United States"),
            percent_american = 100 * american_movies / total_movies)


doubledata <- movies_info %>%
  left_join(RatingGross,
    by = c("name", "year" = "Year"))


topgross <- doubledata %>% 
  filter(doubledata$Rank < 25) %>%  
  arrange(desc(`WorldwideBox Office`)) %>% 
  select(name, score.x, Rank, `WorldwideBox Office`)

duplicate_rows <- topgross[duplicated(topgross), ]
topgross <- unique(topgross)


toprate <- doubledata %>% 
  select(name, score.x, Rank, `WorldwideBox Office`) %>% 
  arrange(desc(score.x)) 

     
topgross_20 <- head(topgross, n = 20) %>% 
  select(name, score.x, `WorldwideBox Office`)
topscore_20 <- head(toprate, n = 20) %>% 
  select(name, score.x, `WorldwideBox Office`)
#Data cleaning for figure 2
# Changing Box Office variables into numerical values
box_office <-box_office %>% 
 mutate(`WorldwideBox Office`=as.numeric(str_replace_all(`WorldwideBox Office`,"[$,]",""))) %>% 
  mutate(`DomesticBox Office`=as.numeric(str_replace_all(`DomesticBox Office`,"[$,]",""))) %>%
  mutate(`InternationalBox Office`=as.numeric(str_replace_all(`InternationalBox Office`,"[$,]","")))

#Getting the Top 20 Box Office
box_office_top20 <- box_office %>%  
  arrange(Rank) %>% 
  head(20) %>% 
  mutate(Movie=ifelse(Movie=="Harry Potter and the Deathly Hallows:…", "Harry Potter and the Deathly Hallows: Part 2",Movie))


#Creating Oscar category data frame
oscars_category <- tibble(
levels(factor(oscars_award$category)))
  

oscars_category <- oscars_category %>% 
  rename("category"="levels(factor(oscars_award$category))") 
  

oscars_category <- oscars_category %>% 
  mutate(broad_category=word(category,1)) %>% 
  mutate(broad_category=
           case_when(broad_category =="ART" ~"ART DIRECTION",
                     broad_category == "BEST" ~ "BEST PICTURE",
                     broad_category == "FILM" ~ "FILM EDITING",
                     broad_category == "ACTOR" | broad_category=="ACTRESS" ~ "ACTING",
                    TRUE ~ broad_category)
            ) 

#Top 20 Box Office Movies and awards dataset by joining dataframes
box_office_top20_awards <- box_office_top20 %>% 
  inner_join(oscars_award,by=c("Movie"="film")) %>% 
  filter(Year == year_film) %>% 
  inner_join(oscars_category)  

box_office_top20_awards <- box_office_top20_awards %>% group_by(Movie,year_film) %>% 
  summarize(total=n()) %>%  inner_join(oscars_award,by=c("Movie"="film")) %>% 
  filter(year_film.x == year_film.y) %>% 
  inner_join(oscars_category)  %>% 
  select(Movie, year_film.x,total,year_ceremony,name,winner,broad_category)
#Data cleaning for figure 3
#Changing movie names so they match across movies_info and box_office_top20

movies_info <- movies_info %>%  mutate(name=case_when(
  name=="Star Wars: Episode VII - The Force Awakens" ~ "Star Wars Ep. VII: The Force Awakens",
  name =="Star Wars: Episode VIII - The Last Jedi" ~ "Star Wars Ep. VIII: The Last Jedi",
TRUE~name)) %>% 
  mutate(company=case_when(
    company=="Walt Disney Animation Studios" | company=="Walt Disney Pictures" ~"Walt Disney",
TRUE~company))

#Joinining movies_info and box_office_top20

box_office_top20_info<- box_office_top20 %>%
  inner_join(movies_info,by=c("Movie"="name","Year"="year"))

#Making top20 main character's race data frame
top20_race <- data.frame(star=box_office_top20_info$star,Race=c("White","White","White","White","White","White","Black","White","White","White","White","Black","White","White","White","White","White","White","White","White"))

#Joining box_office_top20_info with top20_race dataframe
box_office_top20_info <- box_office_top20_info %>% data.frame(top20_race) %>% select(!star.1)
#Data cleaning for figure 4

bechdelset <- bechdelset %>% 
  mutate(set_factor = factor(set)) 

bechdelsetav <- bechdelset %>% 
  group_by(set_factor, clean_test) %>% 
  summarize(count = n ())

bechdelsetav <- bechdelsetav %>% 
  mutate(percent = count/ 20 * 100)

bechdelav <- bechdel %>% 
  group_by(clean_test) %>%  
  summarize (count = n ())

bechdelav <- bechdelav %>%  
    mutate(percent = round(count/ 1794 * 100)) %>% 
    mutate(set_factor = "Average Bechdel Scores")

jointav <- rbind(bechdelsetav, bechdelav) 


jointav$clean_test <- factor(jointav$clean_test, levels = c("nowomen", "notalk", "men", "dubious", "ok"))
#Figure 1
colors <- c("#AC2528", "#E4792C", "#764484", "#346491", "#448746")

fig1<-plot_ly(bechdelset, x = ~score.x, y = ~`WorldwideBox Office`, color = ~clean_test, colors = colors, type = 'scatter', mode = 'markers',
  hoverinfo = 'text',
  text = ~paste('</br>', name, 
                '</br>', "IMDB Score:", score.x, 
                '</br>', "Worldwide Grossing:", comma(`WorldwideBox Office`))) %>% 
  layout(title = 'IMDB Score vs. Amount of Money Grossed', 
            xaxis = list(title = 'IMDB Score'), 
            yaxis = list(title = 'Worldwide Box Office'), 
           legend = list(title = list(text = "Bechdel Test Score"),
                       titles = list(topgross_20 = "Top 20 Grossing", topscore_20 = "Top 20 Scored")))
#Figure 2

fig2<-box_office_top20_awards %>% 
  ggplot(aes(x = fct_reorder(Movie, total,.fun=sum),alpha=winner,fill=fct_reorder(broad_category,winner))) + 
  geom_bar()+
  theme_classic() +
  theme(legend.position = "right")+
  scale_fill_viridis_d()+
  coord_flip()+
  labs(y="Total Nominations",x="Movie",title="Top 20 Movies with Highest Worldwide Box Office vs Oscars Awards",subtitle = "By Category and Wins",fill="Category",alpha="Winner")+
  theme(plot.title = element_text(face="bold",size=16),plot.subtitle = element_text(size=14),axis.title.x = element_text(size=14),axis.text.x = element_text(size=12),axis.title.y = element_text(size=14),axis.text.y = element_text(size=12))
#Figure 3
fig3<-box_office_top20_info %>% 
  mutate(Profit=gross-budget) %>%
  ggplot(aes(x=budget,y=gross,color=Race,size=Profit)) +
  geom_point()+
  theme_minimal()+
  scale_x_continuous(labels = label_comma())+
  scale_y_continuous(labels = label_comma())+
  scale_size_continuous(labels = label_comma())+
  scale_color_viridis_d(option="E")+
  labs(y="Total Gross",x="Budget",title="Top 20 Movies with Highest Worldwide Box Office",subtitle = "By Profit and Race of Main Character")+
  theme(plot.title = element_text(face="bold",size=12),plot.subtitle = element_text(size=10),axis.text.x = element_text(size=8))+
  annotate("text",x=200000000,y=1430000000,label="Black Panther",size=3,color="red3")+
   annotate("text",x=260000000,y=1750000000,label="The Lion King (2019)",size=3,color="red3")
#Figure 4


fig4<-hchart(jointav, "column", hcaes(x = set_factor, y = count, group = clean_test), stacking = "percent") %>% 
  hc_title(text = "Bechdel Test Scores") %>% 
  hc_colors(colors) %>% 
  hc_tooltip(pointFormat = "{series.name}: {point.percentage:.1f}%") %>% 
  hc_yAxis(title = "Percentage", labels = list(format = '{value}%')) %>%
  hc_xAxis(title = NULL) %>% 
  hc_colors(colors) %>% 
  hc_legend(enabled = TRUE)

Other Sources

Brueggemann, Tom. “Theater Audiences Shrank by Half in the Last 4 Years. Can Movies Get Them Back?” IMDb, 5 January 2023, https://www.imdb.com/news/ni63899408. Accessed 3 May 2023.
Hickey, Walt, et al. Creating The Next Bechdel Test | FiveThirtyEight, 21 December 2017, https://projects.fivethirtyeight.com/next-bechdel/. Accessed 3 May 2023.
“IMDb.” Wikipedia, https://en.wikipedia.org/wiki/IMDb. Accessed 3 May 2023.
Reynolds, Matt. “You should ignore film ratings on IMDb and Rotten Tomatoes.” Wired UK, 24 October 2017, https://www.wired.co.uk/article/which-film-ranking-site-should-i-trust-rotten-tomatoes-imdb-metacritic. Accessed 3 May 2023.
Ugwu, Reggie. “The Hashtag That Changed the Oscars: An Oral History (Published 2020).” The New York Times, 9 September 2020, https://www.nytimes.com/2020/02/06/movies/oscarssowhite-history.html. Accessed 3 May 2023.
Watkins, Albert. “Race and ethnicity in the United States.” Wikipedia, https://en.wikipedia.org/wiki/Race_and_ethnicity_in_the_United_States. Accessed 3 May 2023.

LS0tCnRpdGxlOiAiTWVhc3VyaW5nIGEgTW92aWXigJlzIFN1Y2Nlc3MgQmV5b25kIHRoZSBEb2xsYXI6IDxicj4gQXJlIFRoZSBIaWdoZXN0IEdyb3NzaW5nIE1vdmllcyBvZiBBbGwgVGltZXMgQWN0dWFsbHnigKZHb29kPyIKYXV0aG9yOiAiRW1tYSBNYWxjb2xtLCBOYSBOZ3V5ZW4iCmRhdGU6ICIyMDIzLTA0LTExIgpvdXRwdXQ6CiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgc3BsaXRfYnk6IE5PTkUKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19mbG9hdDoKICAgICAgdG9jX2NvbGxhcHNlZDogdHJ1ZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQotLS0KPCEtLS0gQmVnaW4gc3R5bGluZyBjb2RlLiAtLS0+CjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+Ci8qIFdob2xlIGRvY3VtZW50OiAqLwpib2R5ewogIGZvbnQtZmFtaWx5OiAiUGFsYXRpbm8gTGlub3R5cGUiLCAiQm9vayBBbnRpcXVhIiwgUGFsYXRpbm8sIHNlcmlmOwogIGZvbnQtc2l6ZTogMTJwdDsKfQpoMS50aXRsZSB7CiAgZm9udC1zaXplOiAzOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQpoNC5hdXRob3IgewogIGZvbnQtc2l6ZTogMThweDsKICB0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KaDQuZGF0ZSB7CiAgZm9udC1zaXplOiAxOHB4OwogIHRleHQtYWxpZ246IGNlbnRlcjsKfQo8L3N0eWxlPgo8IS0tLSBFbmQgc3R5bGluZyBjb2RlLiAtLS0+CgpgYGB7cixlY2hvPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIGV2YWwgPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgdGlkeSA9IFRSVUUpCmBgYAoKCgpgYGB7ciwgZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGRicGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZml2ZXRoaXJ0eWVpZ2h0KQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShydmVzdCkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KG1hZ3JpdHRyKQoKCiNMb2FkaW5nIHJhdyBkYXRhCmJveF9vZmZpY2UgPC1yZWFkX2NzdigiQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UuY3N2IikKbW92aWVzX2luZm8gPC0gcmVhZF9jc3YoIm1vdmllcy5jc3YiKQpvc2NhcnNfYXdhcmQgPC0gcmVhZF9jc3YoInRoZV9vc2Nhcl9hd2FyZC5jc3YiKQpiZWNoZGVsIDwtIGRhdGEuZnJhbWUoYmVjaGRlbCkKYmVjaGRlbHNldCA8LSByZWFkX2NzdigiYmVjaGRlbHNldC5jc3YiKQpCZWNoZGVsbW9uZXkgPC0gcmVhZF9jc3YoIkJlY2hkZWxtb25leS5jc3YiKQpiaW9waWNzIDwtIGRhdGEuZnJhbWUoYmlvcGljcykKUmF0aW5nR3Jvc3MgPC0gcmVhZF9jc3YoIlJhdGluZ0dyb3NzX2VkaXQyLmNzdiIpCgpgYGAKCmBgYHtyLGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMQojYXZlcmFnZSBncm9zc2luZyBmb3IgZWFjaCB0b3AgMjAgc2NvcmVkCgp0b3Bfc2NvcmUgPC0gbW92aWVzX2luZm8gJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZSwgeWVhciwgZ3Jvc3MpICU+JSAKICBhcnJhbmdlKGRlc2Moc2NvcmUpKQoKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKbG93X3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShzY29yZSkKCgpvc2NhcndpbnMgPC0gIG1vdmllc19pbmZvICU+JSAKICBmaWx0ZXIobmFtZSAlaW4lIGMoIlRoZSBMb3JkIG9mIHRoZSBSaW5nczogVGhlIFJldHVybiBvZiB0aGUgS2luZyIsICJUaXRhbmljIiwgIkJlbi1IdXIiLCAiV2VzdCBTaWRlIFN0b3J5IiwgIlRoZSBFbmdsaXNoIFBhdGllbnQiLCAiVGhlIExhc3QgRW1wZXJvciIsICJHaWdpIiwgIlNsdW1kb2cgTWlsbGlvbmFpcmUiLCAiQW1hZGV1cyIsICJHYW5kaGkiKSkgJT4lIAogc3VtbWFyaXplKHN1bT1zdW0oZ3Jvc3MpKQoKCmRvdWJsZWRhdGEgPC0gbW92aWVzX2luZm8gJT4lCiAgbGVmdF9qb2luKFJhdGluZ0dyb3NzLAogICAgYnkgPSBjKCJuYW1lIiwgInllYXIiID0gIlllYXIiKSkKCgp0b3Bncm9zcyA8LSBkb3VibGVkYXRhICU+JSAKICBmaWx0ZXIoZG91YmxlZGF0YSRSYW5rIDwgMjUpICU+JSAgCiAgYXJyYW5nZShkZXNjKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkpICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgUmFuaywgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQoKZHVwbGljYXRlX3Jvd3MgPC0gdG9wZ3Jvc3NbZHVwbGljYXRlZCh0b3Bncm9zcyksIF0KdG9wZ3Jvc3MgPC0gdW5pcXVlKHRvcGdyb3NzKQoKCnRvcHJhdGUgPC0gZG91YmxlZGF0YSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIFJhbmssIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkgJT4lIAogIGFycmFuZ2UoZGVzYyhzY29yZS54KSkgCgogICAgIAp0b3Bncm9zc18yMCA8LSBoZWFkKHRvcGdyb3NzLCBuID0gMjApICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgYFdvcmxkd2lkZUJveCBPZmZpY2VgKQp0b3BzY29yZV8yMCA8LSBoZWFkKHRvcHJhdGUsIG4gPSAyMCkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBgV29ybGR3aWRlQm94IE9mZmljZWApCgoKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSAyCiMgQ2hhbmdpbmcgQm94IE9mZmljZSB2YXJpYWJsZXMgaW50byBudW1lcmljYWwgdmFsdWVzCmJveF9vZmZpY2UgPC1ib3hfb2ZmaWNlICU+JSAKIG11dGF0ZShgV29ybGR3aWRlQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYFdvcmxkd2lkZUJveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUgCiAgbXV0YXRlKGBEb21lc3RpY0JveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBEb21lc3RpY0JveCBPZmZpY2VgLCJbJCxdIiwiIikpKSAlPiUKICBtdXRhdGUoYEludGVybmF0aW9uYWxCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgSW50ZXJuYXRpb25hbEJveCBPZmZpY2VgLCJbJCxdIiwiIikpKQoKI0dldHRpbmcgdGhlIFRvcCAyMCBCb3ggT2ZmaWNlCmJveF9vZmZpY2VfdG9wMjAgPC0gYm94X29mZmljZSAlPiUgIAogIGFycmFuZ2UoUmFuaykgJT4lIAogIGhlYWQoMjApICU+JSAKICBtdXRhdGUoTW92aWU9aWZlbHNlKE1vdmllPT0iSGFycnkgUG90dGVyIGFuZCB0aGUgRGVhdGhseSBIYWxsb3dzOuKApiIsICJIYXJyeSBQb3R0ZXIgYW5kIHRoZSBEZWF0aGx5IEhhbGxvd3M6IFBhcnQgMiIsTW92aWUpKQoKCiNDcmVhdGluZyBPc2NhciBjYXRlZ29yeSBkYXRhIGZyYW1lCm9zY2Fyc19jYXRlZ29yeSA8LSB0aWJibGUoCmxldmVscyhmYWN0b3Iob3NjYXJzX2F3YXJkJGNhdGVnb3J5KSkpCiAgCgpvc2NhcnNfY2F0ZWdvcnkgPC0gb3NjYXJzX2NhdGVnb3J5ICU+JSAKICByZW5hbWUoImNhdGVnb3J5Ij0ibGV2ZWxzKGZhY3Rvcihvc2NhcnNfYXdhcmQkY2F0ZWdvcnkpKSIpIAogIAoKb3NjYXJzX2NhdGVnb3J5IDwtIG9zY2Fyc19jYXRlZ29yeSAlPiUgCiAgbXV0YXRlKGJyb2FkX2NhdGVnb3J5PXdvcmQoY2F0ZWdvcnksMSkpICU+JSAKICBtdXRhdGUoYnJvYWRfY2F0ZWdvcnk9CiAgICAgICAgICAgY2FzZV93aGVuKGJyb2FkX2NhdGVnb3J5ID09IkFSVCIgfiJBUlQgRElSRUNUSU9OIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkJFU1QiIH4gIkJFU1QgUElDVFVSRSIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJGSUxNIiB+ICJGSUxNIEVESVRJTkciLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiQUNUT1IiIHwgYnJvYWRfY2F0ZWdvcnk9PSJBQ1RSRVNTIiB+ICJBQ1RJTkciLAogICAgICAgICAgICAgICAgICAgIFRSVUUgfiBicm9hZF9jYXRlZ29yeSkKICAgICAgICAgICAgKSAKCiNUb3AgMjAgQm94IE9mZmljZSBNb3ZpZXMgYW5kIGF3YXJkcyBkYXRhc2V0IGJ5IGpvaW5pbmcgZGF0YWZyYW1lcwpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwICU+JSAKICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcihZZWFyID09IHllYXJfZmlsbSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgCgpib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyA8LSBib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyAlPiUgZ3JvdXBfYnkoTW92aWUseWVhcl9maWxtKSAlPiUgCiAgc3VtbWFyaXplKHRvdGFsPW4oKSkgJT4lICBpbm5lcl9qb2luKG9zY2Fyc19hd2FyZCxieT1jKCJNb3ZpZSI9ImZpbG0iKSkgJT4lIAogIGZpbHRlcih5ZWFyX2ZpbG0ueCA9PSB5ZWFyX2ZpbG0ueSkgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2NhdGVnb3J5KSAgJT4lIAogIHNlbGVjdChNb3ZpZSwgeWVhcl9maWxtLngsdG90YWwseWVhcl9jZXJlbW9ueSxuYW1lLHdpbm5lcixicm9hZF9jYXRlZ29yeSkKYGBgCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDMKI0NoYW5naW5nIG1vdmllIG5hbWVzIHNvIHRoZXkgbWF0Y2ggYWNyb3NzIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgptb3ZpZXNfaW5mbyA8LSBtb3ZpZXNfaW5mbyAlPiUgIG11dGF0ZShuYW1lPWNhc2Vfd2hlbigKICBuYW1lPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSSAtIFRoZSBGb3JjZSBBd2FrZW5zIiB+ICJTdGFyIFdhcnMgRXAuIFZJSTogVGhlIEZvcmNlIEF3YWtlbnMiLAogIG5hbWUgPT0iU3RhciBXYXJzOiBFcGlzb2RlIFZJSUkgLSBUaGUgTGFzdCBKZWRpIiB+ICJTdGFyIFdhcnMgRXAuIFZJSUk6IFRoZSBMYXN0IEplZGkiLApUUlVFfm5hbWUpKSAlPiUgCiAgbXV0YXRlKGNvbXBhbnk9Y2FzZV93aGVuKAogICAgY29tcGFueT09IldhbHQgRGlzbmV5IEFuaW1hdGlvbiBTdHVkaW9zIiB8IGNvbXBhbnk9PSJXYWx0IERpc25leSBQaWN0dXJlcyIgfiJXYWx0IERpc25leSIsClRSVUV+Y29tcGFueSkpCgojSm9pbmluaW5nIG1vdmllc19pbmZvIGFuZCBib3hfb2ZmaWNlX3RvcDIwCgpib3hfb2ZmaWNlX3RvcDIwX2luZm88LSBib3hfb2ZmaWNlX3RvcDIwICU+JQogIGlubmVyX2pvaW4obW92aWVzX2luZm8sYnk9YygiTW92aWUiPSJuYW1lIiwiWWVhciI9InllYXIiKSkKCiNNYWtpbmcgdG9wMjAgbWFpbiBjaGFyYWN0ZXIncyByYWNlIGRhdGEgZnJhbWUKdG9wMjBfcmFjZSA8LSBkYXRhLmZyYW1lKHN0YXI9Ym94X29mZmljZV90b3AyMF9pbmZvJHN0YXIsUmFjZT1jKCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJCbGFjayIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiQmxhY2siLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIikpCgojSm9pbmluZyBib3hfb2ZmaWNlX3RvcDIwX2luZm8gd2l0aCB0b3AyMF9yYWNlIGRhdGFmcmFtZQpib3hfb2ZmaWNlX3RvcDIwX2luZm8gPC0gYm94X29mZmljZV90b3AyMF9pbmZvICU+JSBkYXRhLmZyYW1lKHRvcDIwX3JhY2UpICU+JSBzZWxlY3QoIXN0YXIuMSkKCmBgYAoKYGBge3IsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0RhdGEgY2xlYW5pbmcgZm9yIGZpZ3VyZSA0CgpiZWNoZGVsc2V0IDwtIGJlY2hkZWxzZXQgJT4lIAogIG11dGF0ZShzZXRfZmFjdG9yID0gZmFjdG9yKHNldCkpIAoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXQgJT4lIAogIGdyb3VwX2J5KHNldF9mYWN0b3IsIGNsZWFuX3Rlc3QpICU+JSAKICBzdW1tYXJpemUoY291bnQgPSBuICgpKQoKYmVjaGRlbHNldGF2IDwtIGJlY2hkZWxzZXRhdiAlPiUgCiAgbXV0YXRlKHBlcmNlbnQgPSBjb3VudC8gMjAgKiAxMDApCgpiZWNoZGVsYXYgPC0gYmVjaGRlbCAlPiUgCiAgZ3JvdXBfYnkoY2xlYW5fdGVzdCkgJT4lICAKICBzdW1tYXJpemUgKGNvdW50ID0gbiAoKSkKCmJlY2hkZWxhdiA8LSBiZWNoZGVsYXYgJT4lICAKICAgIG11dGF0ZShwZXJjZW50ID0gcm91bmQoY291bnQvIDE3OTQgKiAxMDApKSAlPiUgCiAgICBtdXRhdGUoc2V0X2ZhY3RvciA9ICJBdmVyYWdlIEJlY2hkZWwgU2NvcmVzIikKCmpvaW50YXYgPC0gcmJpbmQoYmVjaGRlbHNldGF2LCBiZWNoZGVsYXYpIAoKCmpvaW50YXYkY2xlYW5fdGVzdCA8LSBmYWN0b3Ioam9pbnRhdiRjbGVhbl90ZXN0LCBsZXZlbHMgPSBjKCJub3dvbWVuIiwgIm5vdGFsayIsICJtZW4iLCAiZHViaW91cyIsICJvayIpKQoKYGBgCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IkEgc2NhdHRlciBwbG90IHNob3dpbmcgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBJTURiIHNjb3JlIGFuZCB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBmb3IgbW92aWVzIHdpdGggZGlmZmVyZW50IEJlY2hkZWwgdGVzdCBzY29yZXMuIEVhY2ggcG9pbnQgcmVwcmVzZW50cyBhIG1vdmllIGFuZCBpcyBjb2xvcmVkIGJhc2VkIG9uIGl0cyBCZWNoZGVsIHRlc3Qgc2NvcmUuIFRoZSBsZWdlbmQgc2hvd3MgdGhlIGZpdmUgQmVjaGRlbCB0ZXN0IHNjb3Jlczogbm8gd29tZW4sIG5vIHRhbGssIG1lbiwgZHViaW91cywgYW5kIG9rLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIElNRGIgc2NvcmUsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGluIG1pbGxpb25zLyBiaWxsaW9ucyBvZiBkb2xsYXJzLiBUaGUgdG9vbHRpcCBkaXNwbGF5cyB0aGUgbW92aWUgbmFtZSwgSU1EYiBzY29yZSwgYW5kIHdvcmxkd2lkZSBncm9zc2luZyBmb3IgZWFjaCBwb2ludC4ifQojRmlndXJlIDEKY29sb3JzIDwtIGMoIiNBQzI1MjgiLCAiI0U0NzkyQyIsICIjNzY0NDg0IiwgIiMzNDY0OTEiLCAiIzQ0ODc0NiIpCgpmaWcxPC1wbG90X2x5KGJlY2hkZWxzZXQsIHggPSB+c2NvcmUueCwgeSA9IH5gV29ybGR3aWRlQm94IE9mZmljZWAsIGNvbG9yID0gfmNsZWFuX3Rlc3QsIGNvbG9ycyA9IGNvbG9ycywgdHlwZSA9ICdzY2F0dGVyJywgbW9kZSA9ICdtYXJrZXJzJywKICBob3ZlcmluZm8gPSAndGV4dCcsCiAgdGV4dCA9IH5wYXN0ZSgnPC9icj4nLCBuYW1lLCAKICAgICAgICAgICAgICAgICc8L2JyPicsICJJTURCIFNjb3JlOiIsIHNjb3JlLngsIAogICAgICAgICAgICAgICAgJzwvYnI+JywgIldvcmxkd2lkZSBHcm9zc2luZzoiLCBjb21tYShgV29ybGR3aWRlQm94IE9mZmljZWApKSkgJT4lIAogIGxheW91dCh0aXRsZSA9ICdJTURCIFNjb3JlIHZzLiBBbW91bnQgb2YgTW9uZXkgR3Jvc3NlZCcsIAogICAgICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAnSU1EQiBTY29yZScpLCAKICAgICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gJ1dvcmxkd2lkZSBCb3ggT2ZmaWNlJyksIAogICAgICAgICAgIGxlZ2VuZCA9IGxpc3QodGl0bGUgPSBsaXN0KHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlIiksCiAgICAgICAgICAgICAgICAgICAgICAgdGl0bGVzID0gbGlzdCh0b3Bncm9zc18yMCA9ICJUb3AgMjAgR3Jvc3NpbmciLCB0b3BzY29yZV8yMCA9ICJUb3AgMjAgU2NvcmVkIikpKQoKCgoKYGBgCgoKYGBge3IsZmlnLmFsdD0iVGhpcyBiYXIgZ3JhcGggc2hvd3MgdGhlIHRvdGFsIG51bWJlciBvZiBvc2NhciBhd2FyZHMgbm9taW5hdGlvbnMgb2YgdGhlIHRvcCAyMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSBieSBDYXRlZ29yeSBhbmQgV2lucyIsZWNobz1GQUxTRSwgbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLCBmaWcuaGVpZ2h0ID04LCBmaWcud2lkdGggPSAxMH0KI0ZpZ3VyZSAyCgpmaWcyPC1ib3hfb2ZmaWNlX3RvcDIwX2F3YXJkcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZmN0X3Jlb3JkZXIoTW92aWUsIHRvdGFsLC5mdW49c3VtKSxhbHBoYT13aW5uZXIsZmlsbD1mY3RfcmVvcmRlcihicm9hZF9jYXRlZ29yeSx3aW5uZXIpKSkgKyAKICBnZW9tX2JhcigpKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IikrCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSsKICBjb29yZF9mbGlwKCkrCiAgbGFicyh5PSJUb3RhbCBOb21pbmF0aW9ucyIseD0iTW92aWUiLHRpdGxlPSJUb3AgMjAgTW92aWVzIHdpdGggSGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSB2cyBPc2NhcnMgQXdhcmRzIixzdWJ0aXRsZSA9ICJCeSBDYXRlZ29yeSBhbmQgV2lucyIsZmlsbD0iQ2F0ZWdvcnkiLGFscGhhPSJXaW5uZXIiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLHNpemU9MTYpLHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9MTIpLGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRleHQueSA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSkKCgpgYGAKCgpgYGB7cixlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IlRoaXMgc2NhdHRlciBwbG90IGRpc3BsYXlzIHRoZSB0b3AgMjAgaGlnaGVzdCBncm9zc2luZyBtb3ZpZXMgb2YgYWxsIHRpbWUgYnkgdGhlaXIgcHJvZml0IGFuZCB0aGUgbWFpbiBjaGFyYWN0ZXIncyByYWNlLiBJdCBzaG93cyB0aGF0IG91dCBvZiAyMCBtb3ZpZXMsIDIgaGFzIGEgbm9uLXdoaXRlIG1haW4gY2hhcmFjdGVyLiJ9CiNGaWd1cmUgMwpmaWczPC1ib3hfb2ZmaWNlX3RvcDIwX2luZm8gJT4lIAogIG11dGF0ZShQcm9maXQ9Z3Jvc3MtYnVkZ2V0KSAlPiUKICBnZ3Bsb3QoYWVzKHg9YnVkZ2V0LHk9Z3Jvc3MsY29sb3I9UmFjZSxzaXplPVByb2ZpdCkpICsKICBnZW9tX3BvaW50KCkrCiAgdGhlbWVfbWluaW1hbCgpKwogIHNjYWxlX3hfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfc2l6ZV9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZChvcHRpb249IkUiKSsKICBsYWJzKHk9IlRvdGFsIEdyb3NzIix4PSJCdWRnZXQiLHRpdGxlPSJUb3AgMjAgTW92aWVzIHdpdGggSGlnaGVzdCBXb3JsZHdpZGUgQm94IE9mZmljZSIsc3VidGl0bGUgPSAiQnkgUHJvZml0IGFuZCBSYWNlIG9mIE1haW4gQ2hhcmFjdGVyIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIixzaXplPTEyKSxwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTApLGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemU9OCkpKwogIGFubm90YXRlKCJ0ZXh0Iix4PTIwMDAwMDAwMCx5PTE0MzAwMDAwMDAsbGFiZWw9IkJsYWNrIFBhbnRoZXIiLHNpemU9Myxjb2xvcj0icmVkMyIpKwogICBhbm5vdGF0ZSgidGV4dCIseD0yNjAwMDAwMDAseT0xNzUwMDAwMDAwLGxhYmVsPSJUaGUgTGlvbiBLaW5nICgyMDE5KSIsc2l6ZT0zLGNvbG9yPSJyZWQzIikKCiAgCmBgYAoKYGBge3IsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsZmlnLmFsdD0iQSBzdGFja2VkIGNvbHVtbiBjaGFydCBzaG93aW5nIHRoZSBwZXJjZW50YWdlIGRpc3RyaWJ1dGlvbiBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QgYnkgZGlmZmVyZW50IG1vdmllIHNldHMuIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgbW92aWUgc2V0cywgYW5kIHRoZSB5LWF4aXMgcmVwcmVzZW50cyB0aGUgcGVyY2VudGFnZSBvZiBtb3ZpZXMgdGhhdCBwYXNzIHRoZSBCZWNoZGVsIHRlc3QuIFRoZSBjaGFydCBpcyBkaXZpZGVkIGludG8gZml2ZSBjYXRlZ29yaWVzIGJhc2VkIG9uIHRoZSBCZWNoZGVsIHRlc3Qgc2NvcmU6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHRvb2x0aXAgc2hvd3MgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIGZvciBlYWNoIGNhdGVnb3J5IGFuZCBtb3ZpZSBzZXQuIn0KI0ZpZ3VyZSA0CgoKZmlnNDwtaGNoYXJ0KGpvaW50YXYsICJjb2x1bW4iLCBoY2Flcyh4ID0gc2V0X2ZhY3RvciwgeSA9IGNvdW50LCBncm91cCA9IGNsZWFuX3Rlc3QpLCBzdGFja2luZyA9ICJwZXJjZW50IikgJT4lIAogIGhjX3RpdGxlKHRleHQgPSAiQmVjaGRlbCBUZXN0IFNjb3JlcyIpICU+JSAKICBoY19jb2xvcnMoY29sb3JzKSAlPiUgCiAgaGNfdG9vbHRpcChwb2ludEZvcm1hdCA9ICJ7c2VyaWVzLm5hbWV9OiB7cG9pbnQucGVyY2VudGFnZTouMWZ9JSIpICU+JSAKICBoY195QXhpcyh0aXRsZSA9ICJQZXJjZW50YWdlIiwgbGFiZWxzID0gbGlzdChmb3JtYXQgPSAne3ZhbHVlfSUnKSkgJT4lCiAgaGNfeEF4aXModGl0bGUgPSBOVUxMKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX2xlZ2VuZChlbmFibGVkID0gVFJVRSkKYGBgCgojIFRoZSBjdXJyZW50IGFuYXRvbXkgb2YgYSBnb29kIG1vdmllOiBDYW4gd2UgZG8gYmV0dGVyPyAKCiAgRXZlciBzaW5jZSB0aGUg4oCcR29sZGVuIEFnZeKAnSBvZiBjaW5lbWEgaW4gdGhlIDE5MzBzIHRoYXQgbWFya2VkIHNpbGVudCBmaWxtIGEgdGhpbmcgb2YgdGhlIHBhc3QsIHRoZSBmaWxtIGluZHVzdHJ5IGhhcyB3aXRuZXNzZWQgdW5wYXJhbGxlbGVkIHN1Y2Nlc3MgYW5kIGdyb3d0aC4gRnJvbSB0aGUgZmlyc3QgdGVjaG5pY29sb3IgbW92aWVzIGxpa2UgVGhlIFdpemFyZCBvZiBPeiBhbmQgR29uZSBXaXRoIFRoZSBXaW5kIHRvIHRoZSBjb21wdXRhdGlvbmFsbHkgYW5pbWF0ZWQgVGhlIE1hdHJpeCwgSnVyYXNzaWMgUGFyaywgYW5kIHRoZSBmaXJzdCBmdWxseSBjb21wdXRlci1hbmltYXRlZCBmaWxtLCBUb3kgU3RvcnksIHRoZSBpbmR1c3RyeSBvZiBtb3Rpb24gcGljdHVyZXMgaGFzIGNvbnRyaWJ1dGVkIGdyZWF0bHkgbm90IG9ubHkgdG8gdGVjaG5vbG9neSBidXQgYWxzbyB0aGUgZ2xvYmFsIGVjb25vbXkuIEVzcGVjaWFsbHkgaW4gdGhlIGN1cnJlbnQgY2hhbGxlbmdpbmcgZWNvbm9teSBhbmQgdGhlcmUgaGFzIGJlZW4gYSBzaGFycCBkZWNsaW5lIGluIHRoZWF0ZXIgYXVkaWVuY2XigJRbc2hyaW5raW5nIGJ5IGhhbGYgaW4gdGhlIGxhc3QgNCB5ZWFyc11odHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JTURiKSwgZmlsbSBkaXN0cmlidXRvcnMgYXJlIGhlc2l0YW50IHRvIHRha2Ugb24gYSBtb3ZpZSB1bmxlc3MgdGhleSBjYW4gc2VlIGl0cyBzdWNjZXNzIGZpcnN0IGhhbmQuIFRoZXJlZm9yZSwgYm94LW9mZmljZSwgb3IgdGhlIGVudGlyZSBlYXJuaW5ncyBnZW5lcmF0ZWQgdGhyb3VnaCBtb3ZpZSB0aWNrZXQgc2FsZXMsIGhhcyBiZWVuIHJlY29nbml6ZWQgYXMgb25lIG9mIHRoZSBwcmltYXJ5IGluZGljYXRvcnMgdG8gY29tcGFyZSBmaWxtIHN1Y2Nlc3MuIE1hbnkgcmVseSBvbiBpdCB0byBkZWNpZGUgd2hldGhlciB0byBib3RoIHByb2R1Y2UgYW5kIHdhdGNoIGEgZmlsbS4gSG93ZXZlciwgYXJlIGhpZ2ggZ3Jvc3NpbmcgbW92aWVzIGFjdHVhbGx54oCmIGdvb2Q/IElmIHNvLCB3aGF0IGVsc2UgY2FuIHdlIHVzZSB0byBtZWFzdXJlIHRoZW0/ICAKCiAgT25lIG9mIHRoZSBwb3B1bGFyIG90aGVyIGluZGljYXRvcnMgdXNlZCB3b3JsZHdpZGUgdG8gYXNzZXNzIGEgbW92aWUgaXMgSU1EYiByYXRpbmcgKG9yIEludGVybmF0aW9uYWwgTW92aWUgRGF0YWJhc2UpLiBJTURiIHJhdGluZyBhbGxvd3MgWzgzIG1pbGxpb25dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZykgb2YgaXRzIHJlZ2lzdGVyZWQgdXNlcnMgIHRvIGNhc3QgYSB2b3RlIChmcm9tIDEgdG8gMTApIG9uIGV2ZXJ5IHJlbGVhc2VkIHRpdGxlIGluIHRoZSBkYXRhYmFzZS4gVGhlc2Ugdm90ZXMgYXJlIHRoZW4gYWdncmVnYXRlZCBhbmQgc3VtbWFyaXplZCBhcyBhIHNpbmdsZSBJTURiIHJhdGluZyB2aXNpYmxlIG9uIElNRGIuY29tLiBBY2Nlc3NpYmxlIHRvIGFueW9uZSwgYW55d2hlcmUsIHRoZXNlIHJhdGluZ3MgYXJlIGEgc2ltcGxpZmllZCB3YXkgdG8gc2VlIHdoYXQgcGVvcGxlIGFsbCBvdmVyIHRoZSB3b3JsZCB0aGluayBhYm91dCBtb3ZpZXMgYW5kIGhhdmUgYmVlbiBhbiBvZnRlbi11c2VkIGluZGljYXRvciBmb3IgYSBmaWxt4oCZcyBwb3B1bGFyaXR5L3F1YWxpdHkuIFRoaXMgbGVkIHVzIHRvIHdvbmRlcjogKkhvdyBkbyB0aGUgbW9zdCBwcm9maXRhYmxlIG1vdmllcyByYW5rIG9uIHRoZSBJTURiIHdlYnNpdGU/KiAKCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJBIHNjYXR0ZXIgcGxvdCBzaG93aW5nIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB0aGUgSU1EYiBzY29yZSBhbmQgd29ybGR3aWRlIGJveCBvZmZpY2UgZ3Jvc3MgZm9yIG1vdmllcyB3aXRoIGRpZmZlcmVudCBCZWNoZGVsIHRlc3Qgc2NvcmVzLiBFYWNoIHBvaW50IHJlcHJlc2VudHMgYSBtb3ZpZSBhbmQgaXMgY29sb3JlZCBiYXNlZCBvbiBpdHMgQmVjaGRlbCB0ZXN0IHNjb3JlLiBUaGUgbGVnZW5kIHNob3dzIHRoZSBmaXZlIEJlY2hkZWwgdGVzdCBzY29yZXM6IG5vIHdvbWVuLCBubyB0YWxrLCBtZW4sIGR1YmlvdXMsIGFuZCBvay4gVGhlIHgtYXhpcyByZXByZXNlbnRzIHRoZSBJTURiIHNjb3JlLCBhbmQgdGhlIHktYXhpcyByZXByZXNlbnRzIHRoZSB3b3JsZHdpZGUgYm94IG9mZmljZSBncm9zcyBpbiBtaWxsaW9ucy8gYmlsbGlvbnMgb2YgZG9sbGFycy4gVGhlIHRvb2x0aXAgZGlzcGxheXMgdGhlIG1vdmllIG5hbWUsIElNRGIgc2NvcmUsIGFuZCB3b3JsZHdpZGUgZ3Jvc3NpbmcgZm9yIGVhY2ggcG9pbnQuIn0KZmlnMQpgYGAKICBGcm9tIG91ciB2aXN1YWxpemF0aW9uIGFib3ZlLCB0aGUgdG9wIDIwIGdyb3NzaW5nIGZpbG1zIGhhdmUgYSByYW5nZSBvZiBzY29yZXMgZnJvbSA2LjIgdG8gOC40IHN0YXJzLiBDb252ZXJzZWx5LCB0aGUgdG9wIDIwIHNjb3JlZCBtb3ZpZXMgb24gSU1EYiBnbG9iYWxseSBncm9zc2VkIGJldHdlZW4gMjgsNDE5LDE1OSBhbmQgMSwxMjAsMjEwLDg5NiBVLlMuIERvbGxhcnMuIFdoZW4gY29tcGFyaW5nIHRoZSBJTURic2NvcmUgYW5kIGFtb3VudCBvZiBtb25leSBncm9zc2VkLCB3ZSBjYW4gb2JzZXJ2ZSB0aGF0IHRoZXJlIGlzbuKAmXQgbXVjaCBvZiBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSByYXRpbmcgb2YgYSBmaWxtIChvciBob3cg4oCcb2JqZWN0aXZlbHkgZ29vZOKAnSBhIG1vdmllIGlzKSBhbmQgdGhlIGFtb3VudCBvZiBtb25leSBpdCBtYWtlcy4KCiAgT24gdGhlIG90aGVyIGhhbmQsIHRvIGludmVzdGlnYXRlIG9waW5pb25zIG9mIGZpbG1zIGZyb20gcHJvZmVzc2lvbmFscyBhbmQgdHJ1c3RlZCBtZW1iZXJzIG9mIHRoZSBmaWxtIGluZHVzdHJ5LCB3ZSBjYW4gdHVybiB0byB0aGUgQWNhZGVteSBBd2FyZHMuIAoKCmBgYHtyLGZpZy53aWR0aD0xMCxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWcyCmBgYAoKICBJdCBzZWVtcyBsaWtlIGEgbW92aWXigJlzIHJldmVudWUgaXMgbm90IGEgc3Ryb25nIGluZGljYXRvciBmb3IgaXRzIGFjY29sYWRlcy4gQW1vbmcgdGhlIHRvcCAyMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCB3b3JsZHdpZGUgYm94IG9mZmljZSBhbmQgdGhlaXIgT3NjYXJzIGF3YXJkcywgb25seSAxMSBtb3ZpZXMgaGFkIGFueSBub21pbmF0aW9ucyBhdCBhbGwuIEZ1cnRoZXJtb3JlLCB0aGlzIGxpc3QgZ2V0cyBldmVuIG1vcmUgbmFycm93ZWQgZG93biBhcyB3ZSBsb29rIGludG8gd2lucy9sb3Nlcy4gVGl0YW5pYywgQXZhdGFyLCBCbGFjayBQYW50aGVyLCBhbmQgRnJvemVuIGFyZSB0aGUgb25seSBtb3ZpZXMgaW4gdGhlIHRvcCAyMCBoaWdoZXN0IHdvcmxkd2lkZSBncm9zc2luZyBtb3ZpZXMgdG8gaGF2ZSBoYWQgYXQgbGVhc3Qgb25lIG5vbWluYXRpb24gYW5kIHdvbiwgd2l0aCBUaXRhbmljIGFzIHRoZSBtb3N0IHByb2xpZmljIHdpdGggMTEgb3V0IG9mIDE0IGNhdGVnb3JpZXMgKGFmdGVyIGdyb3VwaW5nIHNvbWUgb2YgdGhlbSB0b2dldGhlcikuCgogIFRoZSBPc2NhcnMsIGhvd2V2ZXIsIGFyZSBub3QgYW4gb2JqZWN0aXZlIG1lYW5zIG9mIGF3YXJkc2hpcC4gSW4gMjAxNSwgdGhlIGFjYWRlbXkg4oCcYXdhcmRlZCBhbGwgMjAgYWN0aW5nIG5vbWluYXRpb25zIHRvIHdoaXRlIGFjdG9ycyBmb3IgdGhlIGZpcnN0IG9mIHR3byBjb25zZWN1dGl2ZSB5ZWFycywgaW5zcGlyaW5nIEFwcmlsIFJlaWduIHRvIGNyZWF0ZSB0aGUgaGFzaHRhZyAjT3NjYXJzU29XaGl0ZeKAnSBbKFVnd3UsIDIwMjApXShodHRwczovL3d3dy5ueXRpbWVzLmNvbS8yMDIwLzAyLzA2L21vdmllcy9vc2NhcnNzb3doaXRlLWhpc3RvcnkuaHRtbCkuIExlYXZpbmcgdGhlIGRldGVybWluYXRpb24gb2YgZmlsbSBzdWNjZXNzIHRvIHRoZSBBY2FkZW15IHNlZW1zIHRvIHlpZWxkIGEgY2VsZWJyYXRpb24gb2Ygd2hpdGUgY3JlYXRvcnMgYW5kIGFydGlzdHMsIGV4Y2x1ZGluZyBhIHdob2xlIHdvcmxkIG9mIGRpdmVyc2UgY2luZW1hLiAKCgpgYGB7cixlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0Usd2FybmluZz1GQUxTRSxmaWcuYWx0PSJUaGlzIHNjYXR0ZXIgcGxvdCBkaXNwbGF5cyB0aGUgdG9wIDIwIGhpZ2hlc3QgZ3Jvc3NpbmcgbW92aWVzIG9mIGFsbCB0aW1lIGJ5IHRoZWlyIHByb2ZpdCBhbmQgdGhlIG1haW4gY2hhcmFjdGVyJ3MgcmFjZS4gSXQgc2hvd3MgdGhhdCBvdXQgb2YgMjAgbW92aWVzLCAyIGhhcyBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3Rlci4ifQpmaWczCmBgYAoKICBBcyBvZiAyMDIwLCBbYWxtb3N0IGhhbGYgb2YgdGhlIFUuUy4gcG9wdWxhdGlvbiAoNDIuMiUpIGFyZSBwZW9wbGUgb2YgY29sb3JdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JhY2VfYW5kX2V0aG5pY2l0eV9pbl90aGVfVW5pdGVkX1N0YXRlcyM6fjp0ZXh0PUFzJTIwb2YlMjAyMDIwJTJDJTIwV2hpdGUlMjBBbWVyaWNhbnMsbWlub3JpdHklMkMlMjBtYWtpbmclMjB1cCUyMDEyLjElMjUpLiBZZXQsIEhvbGx5d29vZCBmYWlscyB0byBjb25zaWRlciB0aGVtIHdoZW4gbWFraW5nIG1vdmllcy4gSW4gdGhlIHRvcCAyMCBoaWdoZXN0IGdyb3NzaW5nIG1vdmllcyBvZiBhbGwgdGltZSwgb25seSAyIG1vdmllcyBmZWF0dXJlZCBhIG5vbi13aGl0ZSBtYWluIGNoYXJhY3RlcuKAlGJvdGggb2Ygd2hpY2ggd2VyZSBCbGFjayBtYWxlcy4gTm9uZSBvZiB0aGVzZSBtb3ZpZXMgYXJlIGluIHRoZSB0b3AgNSBvZiB0aGlzIGxpc3QgaW4gdGVybXMgb2YgcHJvZml0IGFuZCBncm9zc2luZyB3aGlsZSBvdGhlciB1bmRlcnJlcHJlc2VudGVkIGRlbW9ncmFwaGljcyAoTGF0aW5lcywgRWFzdC9Tb3V0aC9Tb3V0aGVhc3QgQXNpYW5zLCBOYXRpdmUgQW1lcmljYW5zLCBBZnJvIExhdGlub3MsIGV0Yy4pIGFyZSBsZWZ0IGNvbXBsZXRlbHkgb2ZmIHRoZSBzY3JlZW4uIAoKICBGdXJ0aGVybW9yZSwgaW4gdGhlIGhpc3Rvcnkgb2YgdGhlIE9zY2FycyBvbmx5IHRocmVlIHdvbWVuIGhhdmUgd29uIHRoZSBjb3ZldGVkIGJlc3QgZGlyZWN0b3IgdGl0bGUuIFRoaXMgcmVmbGVjdHMgYSBnZW5kZXJlZCBtZWFzdXJlIG9mIHN1Y2Nlc3Mgd2l0aGluIHRoZSBmaWxtIGluZHVzdHJ5LCB3aGVyZSBtb3N0IG9mIHRoZSBwcmFpc2UgZ29lcyB0byBmaWxtcyBhYm91dCBhbmQgY3JlYXRlZCBieSBjaXMgbWVuLiBUbyBtZWFzdXJlIHRoZSByZXByZXNlbnRhdGlvbiBvZiB3b21lbiBpbiBmaWxtcywgd2UgY2FuIHR1cm4gdG8gdGhlIFtCZWNoZGVsIHRlc3RdKGh0dHBzOi8vYmVjaGRlbHRlc3QuY29tLykgd2hpY2ggd2FzIHBvcHVsYXJpemVkIGJ5IEFsaXNvbiBCZWNoZGVsLiBUaGUgdGVzdCBuYW1lcyB0aHJlZSBzaW1wbGUgY3JpdGVyaWE6ICgxKSBpdCBoYXMgdG8gaGF2ZSBhdCBsZWFzdCB0d28gd29tZW4gaW4gaXQsIHdobyAoMikgd2hvIHRhbGsgdG8gZWFjaCBvdGhlciwgYWJvdXQgKDMpIHNvbWV0aGluZyBiZXNpZGVzIGEgbWFuLiBBbHRob3VnaCB0aGlzIHRlc3Qgc2VlbXMgZWFzeSBlbm91Z2gsIG9ubHkgMjUlIG9mIHRoZSB0b3Agc2NvcmVkIGZpbG1zIGFuZCA1MCUgb2YgdGhlIHRvcCBncm9zc2luZyBmaWxtcyBwYXNzZWQuIEludGVyZXN0aW5nbHkgZW5vdWdoLCB3aGVuIGNvbXBhcmluZyB0aGUgdHdvIGRhdGFzZXRzIHRvIGFuIGF2ZXJhZ2UgQmVjaGRlbCB0ZXN0IHNjb3JlIGJyZWFrZG93biwgd2UgY2FuIHNlZSB0aGF0IHRoZSBoaWdoZXN0IGdyb3NzaW5nIGZpbG1zIGFsbCBoYXZlIHdvbWVuIGFuZCBhbiBhYm92ZSBhdmVyYWdlIHNjb3JlIG9mICJvayIgYW5kICJkdWJpb3VzIi4gSG93ZXZlciwgdGhlIGhpZ2hlc3Qgc2NvcmVkIGZpbG1zIGhhdmUgbGVzcyB0aGFuIGF2ZXJhZ2UgIm9rIiBhbmQgZHViaW91cyIgc2NvcmVzLiAKCmBgYHtyLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CmZpZzQKYGBgCgoKICBUaGUgdHJlbmQgd2UgaGF2ZSBpZGVudGlmaWVkIGhlcmUgaXMgc3Ryb25nOiBtb3ZpZXMgdGhhdCBtYWtlIHRoZSBtb3N0IG1vbmV5IGFyZSBtb3N0IG9mdGVuIHRoYW4gbm90IHdoaXRlLSwgbWFsZS0sIGFuZCBFdXJvLWNlbnRyaWMuIEV2ZW4gbG9va2luZyBiZXlvbmQgdGhlIGRvbGxhciwgd2UgY2FuIHNlZSBob3cgc2NvcmluZyBzeXN0ZW1zIGFuZCBhd2FyZHMgYXJlIGJpYXNlZCB0b3dhcmRzIHRoaXMgZGVtb2dyYXBoaWMgYXMgd2VsbC4gQWx0aG91Z2ggdGhlIEFtZXJpY2FuIG1vdmllIGluZHVzdHJ5IGNvbnRpbnVlcyBhY2hpZXZlZCBjb21tZXJjaWFsIHN1Y2Nlc3MsIGl0IGhpc3RvcmljYWxseSBoYXMsIGFuZCBjb250aW51ZXMgdG8sIGxhY2sgc3VmZmljaWVudCByZXByZXNlbnRhdGlvbi4gV2hpbGUgSG9sbHl3b29kIGhhcyB1bmRvdWJ0ZWRseSBjcmVhdGVkIG5vdGFibGUgZmlsbXMgbGlrZSBUaGUgV2l6YXJkIG9mIE96LCBHb25lIFdpdGggVGhlIFdpbmQsIFRoZSBNYXRyaXgsIGFuZCBKdXJhc3NpYyBQYXJrLCB0aGUgaW5kdXN0cnkncyBmb2N1cyBvbiB3aGl0ZSBtYWxlcyBoYXMgcmVzdWx0ZWQgaW4gYSBzaWduaWZpY2FudCBsb3NzIG9mIGRpdmVyc2UgcGVyc3BlY3RpdmVzIGFuZCBjaW5lbWF0aWMgZXhwZXJpZW5jZXMuIEl0IHNlZW1zIGxpa2Ugd2hlbiB3ZSBhcmUgdHJ5aW5nIHRvIGp1ZGdlIGEgbW92aWUsIHdlIHNob3VsZCBoYXZlIGEgYnJvYWRlciByZXBlcnRvaXJlIG9mIG1lYXN1cmVtZW50cyBmb3IgaG93ICpnb29kKiBpdCBpcyBvdGhlciB0aGFuIGp1c3QgbW9uZXkuICAgCgojIERhdGEgRGVzY3JpcHRpb24gCgpBbGwgb2Ygb3VyIGRhdGFzZXRzIHdhcyBzY3JhcGVkIGZyb20gcHVibGljIGRvbWFpbnMgc3VjaCBhcyBba2FnZ2xlLmNvbV0oaHR0cHM6Ly9rYWdnbGUuY29tLykgYW5kIFtmaXZldGhpcnR5ZWlnaHRdKGh0dHBzOi8vZml2ZXRoaXJ0eWVpZ2h0LmNvbS8pLiBJbiB0b3RhbCwgd2UgdXNlZCA0IGRhdGFzZXRzIHRvIHN1cHBvcnQgb3VyIHJlc2VhcmNoIHBhcGVyOiAKPGJyPgoKMS4gICBUaGUgT3NjYXIgQXdhcmQsIFsxOTI3IC0gMjAyM10oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy91bmFuaW1hZC90aGUtb3NjYXItYXdhcmQpOgogICsgMTAsNzY1IE9zY2FyIG5vbWluYXRpb25zIAogICsgc2NyYXBlZCBmcm9tIHRoZSBPZmZpY2lhbCBBY2FkZW15IEF3YXJkcwogICsgNyB2YXJpYWJsZXM6IHllYXIsIG5hbWUsIGZpbG0sIGNhdGVnb3JpZXMsIHdpbiwuLi4KPGJyPgoyLiAgIE1vdmllIEluZHVzdHJ5OiBGb3VyIGRlY2FkZXMgb2YgbW92aWVzLCBbMTk4Ni0yMDE2XShodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL2RhbmllbGdyaWphbHZhcy9tb3ZpZXMpOgogICsgNjgyMCBtb3ZpZXMgaW4gdGhlIGRhdGFzZXQgKGFyb3VuZCAyMjAgbW92aWVzIHBlciB5ZWFyKQogICsgMTUgdmFyaWFibGVzOiBidWRnZXQsIGNvbXBhbnksIGNvdW50cnksIGRpcmVjdG9yLCBnZW5yZSwgbmFtZSwuLi4uCjxicj4KMy4gICBBbGwgVGltZSBXb3JsZHdpZGUgQm94IE9mZmljZSwgWzE5MzktMjAyMV0oaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9ra2hhbmRla2FyL2FsbC10aW1lLXdvcmxkd2lkZS1ib3gtb2ZmaWNlKQogICsgY29udGFpbnMgdGhlIHRvcCBtb3ZpZXMgYmFzZWQgb24gdGhlIGN1bXVsYXRpdmUgd29ybGR3aWRlIGJveCBvZmZpY2UKICArIDc1MTIgbW92aWVzIGFuZCA2IHZhcmlhYmxlczogcmFuaywgd29ybGR3aWRlLWludGVybmF0aW9uYWwtZG9tZXN0aWMgYm94IG9mZmljZSwuLi4KPGJyPgo0LiBCZWNoZGVsIFRlc3QsIDE5NzAtMjAxMyAoZnJvbSBsaWJyYXJ5KGZpdmV0aGlydHllaWdodCkpCiAgKyB0ZXN0cyB3aGV0aGVyIG1vdmllcyBtZWV0IHRoZSBmb2xsb3dpbmcgY3JpdGVyaWE6IFRoZXJlIGFyZSDiiaUgMiAobmFtZWQpIGZlbWFsZSBjaGFyYWN0ZXJzO3RoZXNlIHdvbWVuIHRhbGsgdG8gZWFjaCBvdGhlOyBhYm91dCBzb21ldGhpbmcgb3RoZXIgdGhhbiBhIG1hbi4KICArIDE3OTQgbW92aWVzLCAxNSB2YXJpYWJsZXM6IG1vdmllLCByZXN1bHQsIGdyb3NzaW5ncywgLi4uCiAgCiMgTGltaXRhdGlvbnMKCiMjIERhdGEgCgogIFRoZXJlIGFyZSBzb21lIGxpbWl0YXRpb25zIGluIHRoZSBkYXRhc2V0cy4gRmlyc3Rtb3N0LCB3aGVuIGNvbXBhcmluZyB0aGUgd29ybGR3aWRlIGdyb3NzaW5nIGFtb3VudCBvZiBtb3ZpZXMsIHdlIHdlcmUgdW5hYmxlIHRvIGFjY291bnQgZm9yIGluZmxhdGlvbi4gVGhlIGRhdGFzZXQg4oCcQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2XigJ0gc2NyYXBlZCB0aGUgdGhlIGFtb3VudHMgb2YgaW50ZXJuYXRpb25hbCBncm9zc2luZyBmcm9tIDE5MzkgdG8gMjAyMSwgYnV0IElNRGIgc3RhdGVzIHRoYXQgWyJhbGwgZmlndXJlcyBhcmUgbm90IGFkanVzdGVkIGZvciBpbmZsYXRpb24iXShodHRwczovL2hlbHAuaW1kYi5jb20vYXJ0aWNsZS9jb250cmlidXRpb24vdGl0bGVzL2J1c2luZXNzLWltZGJwcm8tb25seS9HRUpVV1NCQjZXWEgzUlo2IykuIAo8YnI+CiAgQWNjb3JkaW5nIHRvIGEgTWlubmVzb3RhbiBpbmZsYXRpb24gY2FsY3VsYXRvciBbMSBVLlMuIERvbGxhciBpbiAxOTM5IGlzIHdvcnRoICQxOS40OCB0b2RheV0oaHR0cHM6Ly93d3cubWlubmVhcG9saXNmZWQub3JnL2Fib3V0LXVzL21vbmV0YXJ5LXBvbGljeS9pbmZsYXRpb24tY2FsY3VsYXRvciksIHdoaWNoIG1lYW5zIHRoYXQgdGhlIGFtb3VudCBvZiBtb25leSBvY2N1cnJpbmcgaW4gZGlmZmVyZW50IHRpbWUgcGVyaW9kcyBpcyBub3Qgc2NhbGVkIHRvIHNpemUuIEFkZGl0aW9uYWxseSwgaW4gdGhlIGRhdGFzZXQgdXNlZCBmb3IgdGhlIHJhY2lhbCBkaXN0cmlidXRpb24gb2YgT3NjYXJzIHdpbm5lcnMsIHRoZSBkYXRhc2V0IG9ubHkgY29udGFpbmVkIHRoZSByYWNpYWwgaWRlbnRpdGllcyBvZiBiZXN0IGRpcmVjdG9ycywgYWN0b3JzLCBhbmQgYWN0cmVzc2VzLiBUaGlzIGV4Y2x1ZGVzIDIxIG90aGVyIGF3YXJkIGNhdGVnb3JpZXMsIHdoaWNoIGNvdWxkIGhhdmUgZ2l2ZW4gbW9yZSBhY2N1cmF0ZSBpbnNpZ2h0IGludG8gdGhlIGRlbW9ncmFwaGljcyBvZiBPc2NhcnMgd2lubmVycyBhY3Jvc3MgdGhlIGVudGlyZSBhd2FyZCBjZXJlbW9ueS4gICAKPGJyPgogIEZ1cnRoZXJtb3JlLCB3ZSB1c2VkIElNRGIgcmF0aW5ncyB0byBpbnZlc3RpZ2F0ZSBob3cgbW92aWVzIG9mIHZhcmlvdXMgZ3Jvc3NpbmcgYW1vdW50cyBhcmUgc2NvcmVkLCBidXQgaXQgaXMgd29ydGggbm90aW5nIHRoYXQgdGhlIHdlYnNpdGUgY2FsY3VsYXRlcyBhbiBvdmVyYWxsIHNjb3JlIGZyb20gcmVnaXN0ZXJlZCB1c2VycyBjYXN0aW5nIHRoZWlyIHZvdGVzLiBIb3dldmVyLCB0aGVyZSBoYXMgYmVlbiBhIGxhcmdlciBkaXNjdXNzaW9uIGFyb3VuZCB0aGUgbWV0aG9kb2xvZ3kgb2YgdGhpcyBzeXN0ZW0gb2YgbW92aWUtcmF0aW5nLCB3aXRoIHNvbWUgcGVvcGxlIGRlZW1pbmcgb25saW5lIG1vdmllIHZvdGluZyBzeXN0ZW1zIHRvIGJlIGluZWZmZWN0aXZlLiBBZGRpdGlvbmFsbHksIGl0IHdhcyBmb3VuZCB0aGF0IOKAnG1vc3QgSU1EYiB2b3RlcnMgYXJlIG1hbGUsIHdoaWNoIHNlZW1zIHRvIHNrZXcgdGhlIHJhbmtpbmcgaW4gZmF2b3VyIG9mIGZpbG1zIHRoYXQgYXJlIGFpbWVkIG1vcmUgdG93YXJkcyBtZW7igJ0gWyhSZXlub2xkcywgMjAxNyldKGh0dHBzOi8vd3d3LndpcmVkLmNvLnVrL2FydGljbGUvd2hpY2gtZmlsbS1yYW5raW5nLXNpdGUtc2hvdWxkLWktdHJ1c3Qtcm90dGVuLXRvbWF0b2VzLWltZGItbWV0YWNyaXRpYykuIEl0IGlzIHdvcnRoIGFja25vd2xlZGdpbmcgdGhhdCBJTURiIHJhdGluZ3MgYXJlIGEgYmlhc2VkIHN5c3RlbSBvZiByYW5raW5nIGEgZmlsbSwgaG93ZXZlciwgdGhpcyBmdXJ0aGVyIGFpZHMgb3VyIHJlc2VhcmNoIHF1ZXN0aW9uIGluIGlsbHVzdHJhdGluZyB0aGUgY29tcGxpY2F0aW9ucyB0aGF0IGNvbWUgd2l0aCBkZXRlcm1pbmluZyB3aGV0aGVyIGEgbW92aWUgaXMg4oCcZ29vZOKAnS4gCjxicj4KICBBbm90aGVyIGxpbWl0YXRpb24gb2YgdGhpcyBwcm9qZWN0IGlzIHVzaW5nIFRoZSBCZWNoZGVsIHRlc3QgYXMgYSBtZWFzdXJlIG9mIGdlbmRlciBlcXVhbGl0eSBpbiBmaWxtLiBUaGUgQmVjaGRlbCB0ZXN0IGlzIGFuIGluZmFtb3VzIG1lYXN1cmUgb2YgSG9sbHl3b29k4oCZcyBnZW5kZXIgaW1iYWxhbmNlLCBob3dldmVyIGl0IGlzIGFuIG92ZXJzaW1wbGlmaWVkIG1lYW5zIG9mIGFuYWx5emluZyB0aGUgcm9sZSBvZiB3b21lbiBpbiBmaWxtLiBJdCBhc2tzIHRocmVlIHF1ZXN0aW9ucyBvZiBhIG1vdmllLCBhbmQgd2hpbGUgYXN0b25pc2hpbmdseSBtYW55IGZpbG1zIGRvIG5vdCBwYXNzIHRoYXQgYmFyLCB0aGUgc2ltcGxpY2l0eSBvZiB0aGlzIHRlc3Qg4oCcZG9lc27igJl0IGFkZHJlc3MgdGhlIGNvcmUgaW5lcXVhbGl0aWVzIGluIEhvbGx5d29vZCBmaWxtc+KAnSBbKEhpY2tleSBldCBhbCwgMjAxNyldKGh0dHBzOi8vcHJvamVjdHMuZml2ZXRoaXJ0eWVpZ2h0LmNvbS9uZXh0LWJlY2hkZWwvKS4gSW4gdGhlIGRhdGFzZXQgd2UgdXNlZCwgdGhlcmUgd2VyZSBtYW55IGluc3RhbmNlcyBvZiDigJxkdWJpb3Vz4oCdIHdoZXJlIHRoZSByb2xlIG9mIHdvbWVuIGluIHRoZSBmaWxtIHdlcmUgZGViYXRlZCwgYW5kIHRoZXJlZm9yZSwgdGhlIHBhc3MvZmFpbCBzY29yZSBjb3VsZG7igJl0IGJlIGRldGVybWluZWQuIFRvIGNyZWF0ZSBhIG1vcmUgaG9saXN0aWMgYW5hbHlzaXMgb2YgZ2VuZGVyIGVxdWFsaXR5IGluIEhvbGx5d29vZCBpbiB0aGUgZnV0dXJlLCBpdCBpcyB3b3J0aCByZXNlYXJjaGluZyBuZXcgdGVzdHMgdGhhdCBpbmNsdWRlIG5vbi1iaW5hcnkgcGVvcGxlLCBhbmQgZXhwYW5kIHRoZSByZXF1aXJlbWVudHMuIEZvciBpZGVhcywgd2UgY2FuIHR1cm4gdG8g4oCcV2UgcGl0dGVkIDUwIG1vdmllcyBhZ2FpbnN0IDEyIG5ldyB3YXlzIG9mIG1lYXN1cmluZyBIb2xseXdvb2TigJlzIGdlbmRlciBpbWJhbGFuY2XigJ0gd2hpY2ggc3VnZ2VzdHMgbmV3IHRlc3RzIHRoYXQgbG9vayBiZXlvbmQgd2hpdGUgd29tZW4sIGFuZCB0aGUgY2FzdCBhbmQgY3JldyBvZiB0aGUgZmlsbS4gCgojIyBWaXN1YWxpemF0aW9ucy8gT3ZlcmFsbCBSZXNlYXJjaAoKICBPdXIgYXR0ZW1wdCB0aHJvdWdob3V0IHRoaXMgcmVzZWFyY2ggaXMgdG8gc3VnZ2VzdCBkaWZmZXJlbnQgbWV0cmljcyB0byBjb21wYXJlIGFuZCBjb25jbHVkZSBhIG1vdmllIHF1YWxpdHkgYW5kIHB1YmxpYyBwZXJmb3JtYW5jZSBvdGhlciB0aGFuIGl0cyByZXZlbnVlIGFuZCBwcm9maXQgcmV0dXJucy4gRGVzcGl0ZSB0aGUgdmFyaW91cyBpbmRpY2F0b3JzIHdlIGhhdmUgaW5jbHVkZWQgdG8gb2ZmZXIgb3RoZXIgYXZlbnVlcyBpbiBkZXRlcm1pbmluZyBhIGdvb2QgbW92aWUsIG91ciAidGVzdHMiIGFyZSBzaW1wbHkgbm90IGVub3VnaC4gV2l0aCB0aGUgbGltaXRlZCBzY29wZSBvZiBhdmFpbGFibGUgYW5kICJwZXJmZWN0IiBkYXRhLCBvdXIgcmVzZWFyY2ggZmFjZSByZWFsIHdvcmxkIGxpbWl0YXRpb25zIHRoYXQgZmFpbCB0byBhc2NlcnRhaW4gdGhlIHNldmVyaXR5IGFuZCBhcnJheSBvZiBIb2xseXdvb2QncyBpbmVxdWFsaXRpZXMgdGhhdCBhcmUgYmV5b25kIHRoZSB3aGl0ZSBtYWxlIHBvcHVsYXRpb24uIEl0IGFsc28gbGVhdmVzIG91dCB0aGUgcG9wdWxhdGlvbiB0aGF0IHN0YW5kcyBiZWhpbmQgdGhlIGNhbWVyYSBpbiBtb3ZpZSBwcm9kdWN0aW9uIHN1Y2ggYXMgc2NyZWVud3JpdGVycywgcHJvZHVjZXJzLCBzZXQgZGVzaWduZXJzLCBldGMuIEFsbCBvZiB0aGVzZSBhcmUsIGhlbmNlLCByZWZsZWN0ZWQgaW4gb3VyIHZpc3VhbGl6YXRpb25zLiBIb3dldmVyLCB3ZSBob3BlIHRoYXQgb3VyIHJlc2VhcmNoIGNhbiBzZXJ2ZSBhcyBhbiBpbmNlbnRpdmUgZm9yIHRoZSBmaWxtIGluZHVzdHJ5IGFzIHdlbGwgYXMgaXRzIGF1ZGllbmNlIHRvIGJlIG1vcmUgY3JpdGljYWwgb2YgbW92aWVzIGFuZCBtb3ZpZSBtYWtpbmcuICAgICAKCgoKIyBDb2RlIEFwcGVuZGl4CgpgYGB7ciwgZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoc3BsaXRzdGFja3NoYXBlKQpsaWJyYXJ5KGRicGx5cikKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2d0aGVtZXMpCmxpYnJhcnkoZml2ZXRoaXJ0eWVpZ2h0KQpsaWJyYXJ5KGhpZ2hjaGFydGVyKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShydmVzdCkKbGlicmFyeShzY2FsZXMpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGdhcG1pbmRlcikKbGlicmFyeShmb3JjYXRzKQpsaWJyYXJ5KG1hZ3JpdHRyKQoKCiNMb2FkaW5nIHJhdyBkYXRhCmJveF9vZmZpY2UgPC1yZWFkX2NzdigiQWxsIFRpbWUgV29ybGR3aWRlIEJveCBPZmZpY2UuY3N2IikKbW92aWVzX2luZm8gPC0gcmVhZF9jc3YoIm1vdmllcy5jc3YiKQpvc2NhcnNfYXdhcmQgPC0gcmVhZF9jc3YoInRoZV9vc2Nhcl9hd2FyZC5jc3YiKQpiZWNoZGVsIDwtIGRhdGEuZnJhbWUoYmVjaGRlbCkKYmVjaGRlbHNldCA8LSByZWFkX2NzdigiYmVjaGRlbHNldC5jc3YiKQpCZWNoZGVsbW9uZXkgPC0gcmVhZF9jc3YoIkJlY2hkZWxtb25leS5jc3YiKQpiaW9waWNzIDwtIGRhdGEuZnJhbWUoYmlvcGljcykKUmF0aW5nR3Jvc3MgPC0gcmVhZF9jc3YoIlJhdGluZ0dyb3NzX2VkaXQyLmNzdiIpCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMQojYXZlcmFnZSBncm9zc2luZyBmb3IgZWFjaCB0b3AgMjAgc2NvcmVkCgp0b3Bfc2NvcmUgPC0gbW92aWVzX2luZm8gJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZSwgeWVhciwgZ3Jvc3MpICU+JSAKICBhcnJhbmdlKGRlc2Moc2NvcmUpKQoKI2F2ZXJhZ2UgZ3Jvc3NpbmcgZm9yIGVhY2ggdG9wIDIwIHNjb3JlZAoKbG93X3Njb3JlIDwtIG1vdmllc19pbmZvICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUsIHllYXIsIGdyb3NzKSAlPiUgCiAgYXJyYW5nZShzY29yZSkKCgoKb3NjYXJ3aW5zIDwtICBtb3ZpZXNfaW5mbyAlPiUgCiAgZmlsdGVyKG5hbWUgJWluJSBjKCJUaGUgTG9yZCBvZiB0aGUgUmluZ3M6IFRoZSBSZXR1cm4gb2YgdGhlIEtpbmciLCAiVGl0YW5pYyIsICJCZW4tSHVyIiwgIldlc3QgU2lkZSBTdG9yeSIsICJUaGUgRW5nbGlzaCBQYXRpZW50IiwgIlRoZSBMYXN0IEVtcGVyb3IiLCAiR2lnaSIsICJTbHVtZG9nIE1pbGxpb25haXJlIiwgIkFtYWRldXMiLCAiR2FuZGhpIikpICU+JSAKIHN1bW1hcml6ZShzdW09c3VtKGdyb3NzKSkKCm1vdmllc19pbmZvICU+JQogIGdyb3VwX2J5KHllYXIpICU+JQogIHN1bW1hcml6ZSh0b3RhbF9tb3ZpZXMgPSBuKCksCiAgICAgICAgICAgIGFtZXJpY2FuX21vdmllcyA9IHN1bShjb3VudHJ5ID09ICJVbml0ZWQgU3RhdGVzIiksCiAgICAgICAgICAgIHBlcmNlbnRfYW1lcmljYW4gPSAxMDAgKiBhbWVyaWNhbl9tb3ZpZXMgLyB0b3RhbF9tb3ZpZXMpCgoKZG91YmxlZGF0YSA8LSBtb3ZpZXNfaW5mbyAlPiUKICBsZWZ0X2pvaW4oUmF0aW5nR3Jvc3MsCiAgICBieSA9IGMoIm5hbWUiLCAieWVhciIgPSAiWWVhciIpKQoKCnRvcGdyb3NzIDwtIGRvdWJsZWRhdGEgJT4lIAogIGZpbHRlcihkb3VibGVkYXRhJFJhbmsgPCAyNSkgJT4lICAKICBhcnJhbmdlKGRlc2MoYFdvcmxkd2lkZUJveCBPZmZpY2VgKSkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBSYW5rLCBgV29ybGR3aWRlQm94IE9mZmljZWApCgpkdXBsaWNhdGVfcm93cyA8LSB0b3Bncm9zc1tkdXBsaWNhdGVkKHRvcGdyb3NzKSwgXQp0b3Bncm9zcyA8LSB1bmlxdWUodG9wZ3Jvc3MpCgoKdG9wcmF0ZSA8LSBkb3VibGVkYXRhICU+JSAKICBzZWxlY3QobmFtZSwgc2NvcmUueCwgUmFuaywgYFdvcmxkd2lkZUJveCBPZmZpY2VgKSAlPiUgCiAgYXJyYW5nZShkZXNjKHNjb3JlLngpKSAKCiAgICAgCnRvcGdyb3NzXzIwIDwtIGhlYWQodG9wZ3Jvc3MsIG4gPSAyMCkgJT4lIAogIHNlbGVjdChuYW1lLCBzY29yZS54LCBgV29ybGR3aWRlQm94IE9mZmljZWApCnRvcHNjb3JlXzIwIDwtIGhlYWQodG9wcmF0ZSwgbiA9IDIwKSAlPiUgCiAgc2VsZWN0KG5hbWUsIHNjb3JlLngsIGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkKCgoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDIKIyBDaGFuZ2luZyBCb3ggT2ZmaWNlIHZhcmlhYmxlcyBpbnRvIG51bWVyaWNhbCB2YWx1ZXMKYm94X29mZmljZSA8LWJveF9vZmZpY2UgJT4lIAogbXV0YXRlKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYD1hcy5udW1lcmljKHN0cl9yZXBsYWNlX2FsbChgV29ybGR3aWRlQm94IE9mZmljZWAsIlskLF0iLCIiKSkpICU+JSAKICBtdXRhdGUoYERvbWVzdGljQm94IE9mZmljZWA9YXMubnVtZXJpYyhzdHJfcmVwbGFjZV9hbGwoYERvbWVzdGljQm94IE9mZmljZWAsIlskLF0iLCIiKSkpICU+JQogIG11dGF0ZShgSW50ZXJuYXRpb25hbEJveCBPZmZpY2VgPWFzLm51bWVyaWMoc3RyX3JlcGxhY2VfYWxsKGBJbnRlcm5hdGlvbmFsQm94IE9mZmljZWAsIlskLF0iLCIiKSkpCgojR2V0dGluZyB0aGUgVG9wIDIwIEJveCBPZmZpY2UKYm94X29mZmljZV90b3AyMCA8LSBib3hfb2ZmaWNlICU+JSAgCiAgYXJyYW5nZShSYW5rKSAlPiUgCiAgaGVhZCgyMCkgJT4lIAogIG11dGF0ZShNb3ZpZT1pZmVsc2UoTW92aWU9PSJIYXJyeSBQb3R0ZXIgYW5kIHRoZSBEZWF0aGx5IEhhbGxvd3M64oCmIiwgIkhhcnJ5IFBvdHRlciBhbmQgdGhlIERlYXRobHkgSGFsbG93czogUGFydCAyIixNb3ZpZSkpCgoKI0NyZWF0aW5nIE9zY2FyIGNhdGVnb3J5IGRhdGEgZnJhbWUKb3NjYXJzX2NhdGVnb3J5IDwtIHRpYmJsZSgKbGV2ZWxzKGZhY3Rvcihvc2NhcnNfYXdhcmQkY2F0ZWdvcnkpKSkKICAKCm9zY2Fyc19jYXRlZ29yeSA8LSBvc2NhcnNfY2F0ZWdvcnkgJT4lIAogIHJlbmFtZSgiY2F0ZWdvcnkiPSJsZXZlbHMoZmFjdG9yKG9zY2Fyc19hd2FyZCRjYXRlZ29yeSkpIikgCiAgCgpvc2NhcnNfY2F0ZWdvcnkgPC0gb3NjYXJzX2NhdGVnb3J5ICU+JSAKICBtdXRhdGUoYnJvYWRfY2F0ZWdvcnk9d29yZChjYXRlZ29yeSwxKSkgJT4lIAogIG11dGF0ZShicm9hZF9jYXRlZ29yeT0KICAgICAgICAgICBjYXNlX3doZW4oYnJvYWRfY2F0ZWdvcnkgPT0iQVJUIiB+IkFSVCBESVJFQ1RJT04iLAogICAgICAgICAgICAgICAgICAgICBicm9hZF9jYXRlZ29yeSA9PSAiQkVTVCIgfiAiQkVTVCBQSUNUVVJFIiwKICAgICAgICAgICAgICAgICAgICAgYnJvYWRfY2F0ZWdvcnkgPT0gIkZJTE0iIH4gIkZJTE0gRURJVElORyIsCiAgICAgICAgICAgICAgICAgICAgIGJyb2FkX2NhdGVnb3J5ID09ICJBQ1RPUiIgfCBicm9hZF9jYXRlZ29yeT09IkFDVFJFU1MiIH4gIkFDVElORyIsCiAgICAgICAgICAgICAgICAgICAgVFJVRSB+IGJyb2FkX2NhdGVnb3J5KQogICAgICAgICAgICApIAoKI1RvcCAyMCBCb3ggT2ZmaWNlIE1vdmllcyBhbmQgYXdhcmRzIGRhdGFzZXQgYnkgam9pbmluZyBkYXRhZnJhbWVzCmJveF9vZmZpY2VfdG9wMjBfYXdhcmRzIDwtIGJveF9vZmZpY2VfdG9wMjAgJT4lIAogIGlubmVyX2pvaW4ob3NjYXJzX2F3YXJkLGJ5PWMoIk1vdmllIj0iZmlsbSIpKSAlPiUgCiAgZmlsdGVyKFllYXIgPT0geWVhcl9maWxtKSAlPiUgCiAgaW5uZXJfam9pbihvc2NhcnNfY2F0ZWdvcnkpICAKCmJveF9vZmZpY2VfdG9wMjBfYXdhcmRzIDwtIGJveF9vZmZpY2VfdG9wMjBfYXdhcmRzICU+JSBncm91cF9ieShNb3ZpZSx5ZWFyX2ZpbG0pICU+JSAKICBzdW1tYXJpemUodG90YWw9bigpKSAlPiUgIGlubmVyX2pvaW4ob3NjYXJzX2F3YXJkLGJ5PWMoIk1vdmllIj0iZmlsbSIpKSAlPiUgCiAgZmlsdGVyKHllYXJfZmlsbS54ID09IHllYXJfZmlsbS55KSAlPiUgCiAgaW5uZXJfam9pbihvc2NhcnNfY2F0ZWdvcnkpICAlPiUgCiAgc2VsZWN0KE1vdmllLCB5ZWFyX2ZpbG0ueCx0b3RhbCx5ZWFyX2NlcmVtb255LG5hbWUsd2lubmVyLGJyb2FkX2NhdGVnb3J5KQpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNEYXRhIGNsZWFuaW5nIGZvciBmaWd1cmUgMwojQ2hhbmdpbmcgbW92aWUgbmFtZXMgc28gdGhleSBtYXRjaCBhY3Jvc3MgbW92aWVzX2luZm8gYW5kIGJveF9vZmZpY2VfdG9wMjAKCm1vdmllc19pbmZvIDwtIG1vdmllc19pbmZvICU+JSAgbXV0YXRlKG5hbWU9Y2FzZV93aGVuKAogIG5hbWU9PSJTdGFyIFdhcnM6IEVwaXNvZGUgVklJIC0gVGhlIEZvcmNlIEF3YWtlbnMiIH4gIlN0YXIgV2FycyBFcC4gVklJOiBUaGUgRm9yY2UgQXdha2VucyIsCiAgbmFtZSA9PSJTdGFyIFdhcnM6IEVwaXNvZGUgVklJSSAtIFRoZSBMYXN0IEplZGkiIH4gIlN0YXIgV2FycyBFcC4gVklJSTogVGhlIExhc3QgSmVkaSIsClRSVUV+bmFtZSkpICU+JSAKICBtdXRhdGUoY29tcGFueT1jYXNlX3doZW4oCiAgICBjb21wYW55PT0iV2FsdCBEaXNuZXkgQW5pbWF0aW9uIFN0dWRpb3MiIHwgY29tcGFueT09IldhbHQgRGlzbmV5IFBpY3R1cmVzIiB+IldhbHQgRGlzbmV5IiwKVFJVRX5jb21wYW55KSkKCiNKb2luaW5pbmcgbW92aWVzX2luZm8gYW5kIGJveF9vZmZpY2VfdG9wMjAKCmJveF9vZmZpY2VfdG9wMjBfaW5mbzwtIGJveF9vZmZpY2VfdG9wMjAgJT4lCiAgaW5uZXJfam9pbihtb3ZpZXNfaW5mbyxieT1jKCJNb3ZpZSI9Im5hbWUiLCJZZWFyIj0ieWVhciIpKQoKI01ha2luZyB0b3AyMCBtYWluIGNoYXJhY3RlcidzIHJhY2UgZGF0YSBmcmFtZQp0b3AyMF9yYWNlIDwtIGRhdGEuZnJhbWUoc3Rhcj1ib3hfb2ZmaWNlX3RvcDIwX2luZm8kc3RhcixSYWNlPWMoIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIkJsYWNrIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJCbGFjayIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiLCJXaGl0ZSIsIldoaXRlIiwiV2hpdGUiKSkKCiNKb2luaW5nIGJveF9vZmZpY2VfdG9wMjBfaW5mbyB3aXRoIHRvcDIwX3JhY2UgZGF0YWZyYW1lCmJveF9vZmZpY2VfdG9wMjBfaW5mbyA8LSBib3hfb2ZmaWNlX3RvcDIwX2luZm8gJT4lIGRhdGEuZnJhbWUodG9wMjBfcmFjZSkgJT4lIHNlbGVjdCghc3Rhci4xKQoKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQojRGF0YSBjbGVhbmluZyBmb3IgZmlndXJlIDQKCmJlY2hkZWxzZXQgPC0gYmVjaGRlbHNldCAlPiUgCiAgbXV0YXRlKHNldF9mYWN0b3IgPSBmYWN0b3Ioc2V0KSkgCgpiZWNoZGVsc2V0YXYgPC0gYmVjaGRlbHNldCAlPiUgCiAgZ3JvdXBfYnkoc2V0X2ZhY3RvciwgY2xlYW5fdGVzdCkgJT4lIAogIHN1bW1hcml6ZShjb3VudCA9IG4gKCkpCgpiZWNoZGVsc2V0YXYgPC0gYmVjaGRlbHNldGF2ICU+JSAKICBtdXRhdGUocGVyY2VudCA9IGNvdW50LyAyMCAqIDEwMCkKCmJlY2hkZWxhdiA8LSBiZWNoZGVsICU+JSAKICBncm91cF9ieShjbGVhbl90ZXN0KSAlPiUgIAogIHN1bW1hcml6ZSAoY291bnQgPSBuICgpKQoKYmVjaGRlbGF2IDwtIGJlY2hkZWxhdiAlPiUgIAogICAgbXV0YXRlKHBlcmNlbnQgPSByb3VuZChjb3VudC8gMTc5NCAqIDEwMCkpICU+JSAKICAgIG11dGF0ZShzZXRfZmFjdG9yID0gIkF2ZXJhZ2UgQmVjaGRlbCBTY29yZXMiKQoKam9pbnRhdiA8LSByYmluZChiZWNoZGVsc2V0YXYsIGJlY2hkZWxhdikgCgoKam9pbnRhdiRjbGVhbl90ZXN0IDwtIGZhY3Rvcihqb2ludGF2JGNsZWFuX3Rlc3QsIGxldmVscyA9IGMoIm5vd29tZW4iLCAibm90YWxrIiwgIm1lbiIsICJkdWJpb3VzIiwgIm9rIikpCgpgYGAKCmBgYHtyLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsZmlnLmFsdD0iQSBzY2F0dGVyIHBsb3Qgc2hvd2luZyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIElNRGIgc2NvcmUgYW5kIHdvcmxkd2lkZSBib3ggb2ZmaWNlIGdyb3NzIGZvciBtb3ZpZXMgd2l0aCBkaWZmZXJlbnQgQmVjaGRlbCB0ZXN0IHNjb3Jlcy4gRWFjaCBwb2ludCByZXByZXNlbnRzIGEgbW92aWUgYW5kIGlzIGNvbG9yZWQgYmFzZWQgb24gaXRzIEJlY2hkZWwgdGVzdCBzY29yZS4gVGhlIGxlZ2VuZCBzaG93cyB0aGUgZml2ZSBCZWNoZGVsIHRlc3Qgc2NvcmVzOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB4LWF4aXMgcmVwcmVzZW50cyB0aGUgSU1EYiBzY29yZSwgYW5kIHRoZSB5LWF4aXMgcmVwcmVzZW50cyB0aGUgd29ybGR3aWRlIGJveCBvZmZpY2UgZ3Jvc3MgaW4gbWlsbGlvbnMvIGJpbGxpb25zIG9mIGRvbGxhcnMuIFRoZSB0b29sdGlwIGRpc3BsYXlzIHRoZSBtb3ZpZSBuYW1lLCBJTURiIHNjb3JlLCBhbmQgd29ybGR3aWRlIGdyb3NzaW5nIGZvciBlYWNoIHBvaW50LiJ9CiNGaWd1cmUgMQpjb2xvcnMgPC0gYygiI0FDMjUyOCIsICIjRTQ3OTJDIiwgIiM3NjQ0ODQiLCAiIzM0NjQ5MSIsICIjNDQ4NzQ2IikKCmZpZzE8LXBsb3RfbHkoYmVjaGRlbHNldCwgeCA9IH5zY29yZS54LCB5ID0gfmBXb3JsZHdpZGVCb3ggT2ZmaWNlYCwgY29sb3IgPSB+Y2xlYW5fdGVzdCwgY29sb3JzID0gY29sb3JzLCB0eXBlID0gJ3NjYXR0ZXInLCBtb2RlID0gJ21hcmtlcnMnLAogIGhvdmVyaW5mbyA9ICd0ZXh0JywKICB0ZXh0ID0gfnBhc3RlKCc8L2JyPicsIG5hbWUsIAogICAgICAgICAgICAgICAgJzwvYnI+JywgIklNREIgU2NvcmU6Iiwgc2NvcmUueCwgCiAgICAgICAgICAgICAgICAnPC9icj4nLCAiV29ybGR3aWRlIEdyb3NzaW5nOiIsIGNvbW1hKGBXb3JsZHdpZGVCb3ggT2ZmaWNlYCkpKSAlPiUgCiAgbGF5b3V0KHRpdGxlID0gJ0lNREIgU2NvcmUgdnMuIEFtb3VudCBvZiBNb25leSBHcm9zc2VkJywgCiAgICAgICAgICAgIHhheGlzID0gbGlzdCh0aXRsZSA9ICdJTURCIFNjb3JlJyksIAogICAgICAgICAgICB5YXhpcyA9IGxpc3QodGl0bGUgPSAnV29ybGR3aWRlIEJveCBPZmZpY2UnKSwgCiAgICAgICAgICAgbGVnZW5kID0gbGlzdCh0aXRsZSA9IGxpc3QodGV4dCA9ICJCZWNoZGVsIFRlc3QgU2NvcmUiKSwKICAgICAgICAgICAgICAgICAgICAgICB0aXRsZXMgPSBsaXN0KHRvcGdyb3NzXzIwID0gIlRvcCAyMCBHcm9zc2luZyIsIHRvcHNjb3JlXzIwID0gIlRvcCAyMCBTY29yZWQiKSkpCgoKCgpgYGAKCgpgYGB7cixmaWcud2lkdGg9MTAsZmlnLmhlaWdodD02LGZpZy5hbHQ9IlRoaXMgYmFyIGdyYXBoIHNob3dzIHRoZSB0b3RhbCBudW1iZXIgb2Ygb3NjYXIgYXdhcmRzIG5vbWluYXRpb25zIG9mIHRoZSB0b3AgMjAgbW92aWVzIHdpdGggdGhlIGhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgYnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGV2YWw9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9CiNGaWd1cmUgMgoKZmlnMjwtYm94X29mZmljZV90b3AyMF9hd2FyZHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGZjdF9yZW9yZGVyKE1vdmllLCB0b3RhbCwuZnVuPXN1bSksYWxwaGE9d2lubmVyLGZpbGw9ZmN0X3Jlb3JkZXIoYnJvYWRfY2F0ZWdvcnksd2lubmVyKSkpICsgCiAgZ2VvbV9iYXIoKSsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpKwogIGxhYnMoeT0iVG90YWwgTm9taW5hdGlvbnMiLHg9Ik1vdmllIix0aXRsZT0iVG9wIDIwIE1vdmllcyB3aXRoIEhpZ2hlc3QgV29ybGR3aWRlIEJveCBPZmZpY2UgdnMgT3NjYXJzIEF3YXJkcyIsc3VidGl0bGUgPSAiQnkgQ2F0ZWdvcnkgYW5kIFdpbnMiLGZpbGw9IkNhdGVnb3J5IixhbHBoYT0iV2lubmVyIikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkIixzaXplPTE2KSxwbG90LnN1YnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MTQpLGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplPTE0KSxheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSxheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCksYXhpcy50ZXh0LnkgPSBlbGVtZW50X3RleHQoc2l6ZT0xMikpCgoKYGBgCgoKYGBge3IsZmlnLndpZHRoPTYsZmlnLmhlaWdodD00LGZpZy5hbHQ9IlRoaXMgc2NhdHRlciBwbG90IGRpc3BsYXlzIHRoZSB0b3AgMjAgaGlnaGVzdCBncm9zc2luZyBtb3ZpZXMgb2YgYWxsIHRpbWUgYnkgdGhlaXIgcHJvZml0IGFuZCB0aGUgbWFpbiBjaGFyYWN0ZXIncyByYWNlLiBJdCBzaG93cyB0aGF0IG91dCBvZiAyMCBtb3ZpZXMsIDIgaGFzIGEgbm9uLXdoaXRlIG1haW4gY2hhcmFjdGVyLiIsZXZhbD1GQUxTRSwgbWVzc2FnZT1GQUxTRX0KI0ZpZ3VyZSAzCmZpZzM8LWJveF9vZmZpY2VfdG9wMjBfaW5mbyAlPiUgCiAgbXV0YXRlKFByb2ZpdD1ncm9zcy1idWRnZXQpICU+JQogIGdncGxvdChhZXMoeD1idWRnZXQseT1ncm9zcyxjb2xvcj1SYWNlLHNpemU9UHJvZml0KSkgKwogIGdlb21fcG9pbnQoKSsKICB0aGVtZV9taW5pbWFsKCkrCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IGxhYmVsX2NvbW1hKCkpKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBsYWJlbF9jb21tYSgpKSsKICBzY2FsZV9zaXplX2NvbnRpbnVvdXMobGFiZWxzID0gbGFiZWxfY29tbWEoKSkrCiAgc2NhbGVfY29sb3JfdmlyaWRpc19kKG9wdGlvbj0iRSIpKwogIGxhYnMoeT0iVG90YWwgR3Jvc3MiLHg9IkJ1ZGdldCIsdGl0bGU9IlRvcCAyMCBNb3ZpZXMgd2l0aCBIaWdoZXN0IFdvcmxkd2lkZSBCb3ggT2ZmaWNlIixzdWJ0aXRsZSA9ICJCeSBQcm9maXQgYW5kIFJhY2Ugb2YgTWFpbiBDaGFyYWN0ZXIiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiLHNpemU9MTIpLHBsb3Quc3VidGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0xMCksYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZT04KSkrCiAgYW5ub3RhdGUoInRleHQiLHg9MjAwMDAwMDAwLHk9MTQzMDAwMDAwMCxsYWJlbD0iQmxhY2sgUGFudGhlciIsc2l6ZT0zLGNvbG9yPSJyZWQzIikrCiAgIGFubm90YXRlKCJ0ZXh0Iix4PTI2MDAwMDAwMCx5PTE3NTAwMDAwMDAsbGFiZWw9IlRoZSBMaW9uIEtpbmcgKDIwMTkpIixzaXplPTMsY29sb3I9InJlZDMiKQoKICAKYGBgCgpgYGB7cixldmFsPUZBTFNFLCBtZXNzYWdlPUZBTFNFLGZpZy5hbHQ9IkEgc3RhY2tlZCBjb2x1bW4gY2hhcnQgc2hvd2luZyB0aGUgcGVyY2VudGFnZSBkaXN0cmlidXRpb24gb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0IGJ5IGRpZmZlcmVudCBtb3ZpZSBzZXRzLiBUaGUgeC1heGlzIHJlcHJlc2VudHMgdGhlIG1vdmllIHNldHMsIGFuZCB0aGUgeS1heGlzIHJlcHJlc2VudHMgdGhlIHBlcmNlbnRhZ2Ugb2YgbW92aWVzIHRoYXQgcGFzcyB0aGUgQmVjaGRlbCB0ZXN0LiBUaGUgY2hhcnQgaXMgZGl2aWRlZCBpbnRvIGZpdmUgY2F0ZWdvcmllcyBiYXNlZCBvbiB0aGUgQmVjaGRlbCB0ZXN0IHNjb3JlOiBubyB3b21lbiwgbm8gdGFsaywgbWVuLCBkdWJpb3VzLCBhbmQgb2suIFRoZSB0b29sdGlwIHNob3dzIHRoZSBwZXJjZW50YWdlIG9mIG1vdmllcyBmb3IgZWFjaCBjYXRlZ29yeSBhbmQgbW92aWUgc2V0LiJ9CiNGaWd1cmUgNAoKCmZpZzQ8LWhjaGFydChqb2ludGF2LCAiY29sdW1uIiwgaGNhZXMoeCA9IHNldF9mYWN0b3IsIHkgPSBjb3VudCwgZ3JvdXAgPSBjbGVhbl90ZXN0KSwgc3RhY2tpbmcgPSAicGVyY2VudCIpICU+JSAKICBoY190aXRsZSh0ZXh0ID0gIkJlY2hkZWwgVGVzdCBTY29yZXMiKSAlPiUgCiAgaGNfY29sb3JzKGNvbG9ycykgJT4lIAogIGhjX3Rvb2x0aXAocG9pbnRGb3JtYXQgPSAie3Nlcmllcy5uYW1lfToge3BvaW50LnBlcmNlbnRhZ2U6LjFmfSUiKSAlPiUgCiAgaGNfeUF4aXModGl0bGUgPSAiUGVyY2VudGFnZSIsIGxhYmVscyA9IGxpc3QoZm9ybWF0ID0gJ3t2YWx1ZX0lJykpICU+JQogIGhjX3hBeGlzKHRpdGxlID0gTlVMTCkgJT4lIAogIGhjX2NvbG9ycyhjb2xvcnMpICU+JSAKICBoY19sZWdlbmQoZW5hYmxlZCA9IFRSVUUpCmBgYAoKCiMgT3RoZXIgU291cmNlcwoKQnJ1ZWdnZW1hbm4sIFRvbS4g4oCcVGhlYXRlciBBdWRpZW5jZXMgU2hyYW5rIGJ5IEhhbGYgaW4gdGhlIExhc3QgNCBZZWFycy4gQ2FuIE1vdmllcyBHZXQgVGhlbSBCYWNrP+KAnSBJTURiLCA1IEphbnVhcnkgMjAyMywgaHR0cHM6Ly93d3cuaW1kYi5jb20vbmV3cy9uaTYzODk5NDA4LiBBY2Nlc3NlZCAzIE1heSAyMDIzLgo8YnI+CkhpY2tleSwgV2FsdCwgZXQgYWwuIENyZWF0aW5nIFRoZSBOZXh0IEJlY2hkZWwgVGVzdCB8IEZpdmVUaGlydHlFaWdodCwgMjEgRGVjZW1iZXIgMjAxNywgaHR0cHM6Ly9wcm9qZWN0cy5maXZldGhpcnR5ZWlnaHQuY29tL25leHQtYmVjaGRlbC8uIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4K4oCcSU1EYi7igJ0gV2lraXBlZGlhLCBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JTURiLiBBY2Nlc3NlZCAzIE1heSAyMDIzLgo8YnI+ClJleW5vbGRzLCBNYXR0LiDigJxZb3Ugc2hvdWxkIGlnbm9yZSBmaWxtIHJhdGluZ3Mgb24gSU1EYiBhbmQgUm90dGVuIFRvbWF0b2VzLuKAnSBXaXJlZCBVSywgMjQgT2N0b2JlciAyMDE3LCBodHRwczovL3d3dy53aXJlZC5jby51ay9hcnRpY2xlL3doaWNoLWZpbG0tcmFua2luZy1zaXRlLXNob3VsZC1pLXRydXN0LXJvdHRlbi10b21hdG9lcy1pbWRiLW1ldGFjcml0aWMuIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4KVWd3dSwgUmVnZ2llLiDigJxUaGUgSGFzaHRhZyBUaGF0IENoYW5nZWQgdGhlIE9zY2FyczogQW4gT3JhbCBIaXN0b3J5IChQdWJsaXNoZWQgMjAyMCku4oCdIFRoZSBOZXcgWW9yayBUaW1lcywgOSBTZXB0ZW1iZXIgMjAyMCwgaHR0cHM6Ly93d3cubnl0aW1lcy5jb20vMjAyMC8wMi8wNi9tb3ZpZXMvb3NjYXJzc293aGl0ZS1oaXN0b3J5Lmh0bWwuIEFjY2Vzc2VkIDMgTWF5IDIwMjMuCjxicj4KV2F0a2lucywgQWxiZXJ0LiDigJxSYWNlIGFuZCBldGhuaWNpdHkgaW4gdGhlIFVuaXRlZCBTdGF0ZXMu4oCdIFdpa2lwZWRpYSwgaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvUmFjZV9hbmRfZXRobmljaXR5X2luX3RoZV9Vbml0ZWRfU3RhdGVzLiBBY2Nlc3NlZCAzIE1heSAyMDIzLg==